NOIP2011 聪明的质检员(二分答案)

题解

单调性是当s-y大于0时w越小答案越优,反过来也成立。

所以二分答案。

然后问题是Yi怎么求,最接用前缀和预处理就行了。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=200010;
 8 long long n,m,s,sumv[N],sumn[N],ar[N],al[N],w[N],v[N],y,sum,ans,minn,maxx,l,r,mid;
 9 bool check(long long x){
10     y=0;sum=0;
11     for(int i=1;i<=n;i++){
12         sumv[i]=sumv[i-1];
13         sumn[i]=sumn[i-1];
14         if(w[i]>x)sumv[i]+=v[i],sumn[i]+=1;
15     }
16     for(int i=1;i<=m;i++){
17         y+=(sumv[ar[i]]-sumv[al[i]-1])*(sumn[ar[i]]-sumn[al[i]-1]);
18     }
19     sum=(long long)abs(y-s);
20     if(y>s)return true;
21     else return false;
22 }
23 int main(){
24     scanf("%lld%lld%lld",&n,&m,&s);
25     minn=999999999;
26     for(int i=1;i<=n;i++){
27         scanf("%lld%lld",&w[i],&v[i]);
28         minn=min(minn,w[i]);
29         maxx=max(maxx,w[i]);
30     }
31     for(int i=1;i<=m;i++){
32         scanf("%d%d",&al[i],&ar[i]);
33     }
34     l=minn-1;
35     r=maxx+2;
36     long long ans=19999999999999999;
37     while(l<=r){
38         mid=(l+r)>>1;
39         if(check(mid))l=mid+1;
40         else r=mid-1;
41         if(sum<ans)ans=sum;
42     }
43     printf("%lld",ans);
44     return 0;
45 }
View Code

 

posted @ 2018-08-03 20:16  Xu-daxia  阅读(303)  评论(0编辑  收藏  举报