P1314 [NOIP2011 提高组] 聪明的质监员
考察:二分+前缀和
思路:
易知w变大,y和变小,w变小,y和变大.由此发现y与w的变化关系有单调性.但是这道题求的是abs(Y-S),答案和w的变化并无单调性.我们可以求最小的>=s的Y和最大的<s的Y.再两边求最小值.
真的没必要死脑筋的返回true与false.单纯数值类型可考虑返回数值.
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 typedef long long LL; 5 const int N = 200010; 6 typedef pair<int,int> PII; 7 PII p[N],val[N]; 8 int n,m,cnt[N]; 9 LL s,sum[N]; 10 LL check(LL mid) 11 { 12 memset(sum,0,sizeof sum); 13 memset(cnt,0,sizeof cnt); 14 for(int i=1;i<=n;i++) 15 { 16 if(p[i].first>=mid) cnt[i]++,sum[i]+=p[i].second; 17 sum[i] += sum[i-1]; 18 cnt[i] += cnt[i-1]; 19 } 20 LL res = 0; 21 for(int i=1;i<=m;i++) 22 { 23 int l = val[i].first,r = val[i].second; 24 res+=(cnt[r]-cnt[l-1])*(sum[r]-sum[l-1]); 25 } 26 return res; 27 } 28 int main() 29 { 30 scanf("%d%d%lld",&n,&m,&s); 31 for(int i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second); 32 for(int i=1;i<=m;i++) scanf("%d%d",&val[i].first,&val[i].second); 33 LL l = 0,r = 1e6+5; 34 while(l<r) 35 { 36 LL mid = l+r+1>>1; 37 if(check(mid)>=s) l = mid;//求解Y>=s的最大值w 38 else r = mid-1;//让Y<s的最小值w 39 } 40 LL res2 = abs(s-check(r)); 41 LL res1 = abs(s-check(r+1)); 42 printf("%lld\n",min(res2,res1)); 43 return 0; 44 }