2 条题解
-
1
#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
- 上传者