这题目有毒
花了一个下午在这水(shen)题上,最后才看见0 < S≤10^12。
题目不难:
二分无限逼近答案+前缀和
无视#pragma 那句#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #pragma warning(disable:4996) using namespace std; #define MAXN 200009 #define LL long long LL n , m ; LL S; struct _ { LL val , wei; }a[MAXN]; struct __ { int l , r; }b[MAXN]; LL c[MAXN];//前缀和数组 LL d[MAXN];//前缀和,w[j]>W个数 LL L , R , cnt; void count(LL L, LL R) { if (L == R) return; LL mid = (L + R) >> 1; memset(c , 0 , sizeof(c)); memset(d , 0 , sizeof(d)); for (int i = 1; i <= n; i++) { if (a[i].wei >= mid) { c[i] = c[i - 1] + a[i].val; d[i] = d[i - 1] + 1; } else { c[i] = c[i - 1]; d[i] = d[i - 1]; } } LL ans = 0; for (int i = 1; i <= m; i++) { ans += ((c[b[i].r] - c[b[i].l - 1])*(d[b[i].r] - d[b[i].l - 1])); } if (abs(S - ans) < abs(S - cnt)) cnt = ans; if (S > ans) count(L , mid); if (S == ans) { cnt = ans; return; } if (S < ans) count(mid + 1 , R); } int main() { scanf("%lld%lld%lld" , &n , &m , &S); for (int i = 1; i <= n; i++) { scanf("%lld%lld" , &a[i].wei , &a[i].val); } for (int i = 1; i <= m; i++) scanf("%lld%lld" , &b[i].l , &b[i].r); count(1 , 100000); printf("%lld\n" , abs(cnt - S)); return 0; }