2 条题解

  • 1
    @ 2025-9-14 21:34:44
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    ll n, m, s;
    ll y, ans;
    ll w[200010], v[200010];
    ll l[200010], r[200010];
    ll qzh1[200010], qzh2[200010];
    
    bool check(ll wq) {
    	y = 0;
    	memset(qzh1, 0, sizeof(qzh1));  
    	memset(qzh2, 0, sizeof(qzh2));
    	// 多测不清空,爆零两行泪 
    	for (int i = 1; i <= n; i++) {
    		if (w[i] > wq)  // > 过了检测通过线 
    			qzh1[i] = qzh1[i - 1] + 1, qzh2[i] = qzh2[i - 1] + v[i]; // 前缀和加上 
    		else
    			qzh1[i] = qzh1[i - 1], qzh2[i] = qzh2[i - 1];  // 承继原来的前缀 
    	}
    	for (int i = 1; i <= m; i++) {
    		int rrrr = r[i];
    		int llll = l[i];
    		y += (qzh1[rrrr] - qzh1[llll - 1]) * (qzh2[rrrr] - qzh2[llll - 1]);  // 直接照着式子,简单分析,就会发现这跟式子几乎一模一样/doge 
    	}
    	if (y > s)
    		return 1;  // 判断差值大还是小,为了二分的更改做准备 
    	else
    		return 0;
    }
    
    int main() {
    	cin >> n >> m >> s;
    	for (int i = 1; i <= n; i++)
    		cin >> w[i] >> v[i];
    	for (int i = 1; i <= m; i++)
    		cin >> l[i] >> r[i];
    	int lll = 1;
    	int rrr = 2000010;  
    	ans = s;
    	while (lll <= rrr) { // 二分答案 
    		int mid = lll + (rrr - lll) / 2;  // 防爆ll, 原式子:(lll + rrr) / 2 
    		if (check(mid))
    			lll = mid + 1;
    		else
    			rrr = mid - 1;
    			ans = min(ans, llabs(s - y)); // 为了防止爆int, 所以写llabs 
    	}
    	cout << ans;
    }
    
    
    
    • 1
      @ 2025-1-26 10:59:21
      #include<iostream>
      #include<algorithm>
      #include<cstdio>
      #define int long long
      
      using namespace std;
      
      int n,m,s;
      int w[200500],v[200500];
      int l[200500],r[200500];
      
      int sum_n[200500],sum_v[200500];
      
      long long ans = 0;
      
      void init()
      {
          scanf("%lld%lld%lld",&n,&m,&s);
          for(int i = 1;i <= n; i++)
              scanf("%lld%lld",&w[i],&v[i]);
          for(int i = 1;i <= m; i++)
              scanf("%lld%lld",&l[i],&r[i]);
          
          return ;
      }
      
      long long check(int W)
      {
          long long ans = 0;
          for(int i = 1;i <= n; i++)
          {
              if( W > w[i] )// 要用前缀和,不然会炸掉!!!
              {
                  sum_n[i] = sum_n[i-1];
                  sum_v[i] = sum_v[i-1]; 
              }
              else
              {
                  sum_n[i] = sum_n[i-1] + 1;
                  sum_v[i] = sum_v[i-1] + v[i]; 
              }
          }
      
          for(int i = 1;i <= m; i++)
          {
              long long a,b;
              a = sum_v[r[i]] - sum_v[l[i]-1];
              b = sum_n[r[i]] - sum_n[l[i]-1];
              ans += a*b;
          }
      
          return ans;
      }
      
      long long _abs(long long a)
      {
          if( a > 0 )
              return a;
          return -a;
      }
      
      signed main()
      {
          init();
      
          int left = 0,right = 1000000,mid;
      
          while( left <= right )
          {
              mid  = (left + right)>>1;
              if( check(mid) > s )
                  left = mid + 1;
              else    
                  right = mid - 1;
          }
          ans = _abs(check(left) - s);
          
          if( _abs(check(right) - s) < ans )
              ans = _abs(check(right) - s);
          
          printf("%lld",ans);
          return 0;
      }
      
      • 1

      信息

      ID
      720
      时间
      1000ms
      内存
      128MiB
      难度
      6
      标签
      递交数
      16
      已通过
      12
      上传者