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;
    }
    
    
    

    信息

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