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; }
-
1
#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
- 上传者