首页 > 代码库 > [NOIP2011]聪明的质监员 题解
[NOIP2011]聪明的质监员 题解
题目大意:
额……貌似蛮清晰的,就不赘述了。
思路:
首先不难发现M越大Y越小,因此可以二分答案(方向不要弄错),二分出最小的不小于S的Y即可。而计算Y时可用前缀和O(n+m)求得。两种边界情况也要考虑一下(同时long long不要少开)。
代码:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 #define ll long long 5 const int M=200008; 6 int n,m,i,h,t,k,mn,mx,mid,w[M],v[M],l[M],r[M]; 7 ll s,sum[M],num[M]; 8 9 ll abs(ll x) { return x>0?x:-x; } 10 11 ll cal(int p) 12 { 13 int i; ll t=0; 14 for (i=1;i<=n;i++) 15 if (w[i]>=p) num[i]=num[i-1]+1,sum[i]=sum[i-1]+v[i]; 16 else num[i]=num[i-1],sum[i]=sum[i-1]; 17 for (i=1;i<=m;i++) t+=(num[r[i]]-num[l[i]-1])*(sum[r[i]]-sum[l[i]-1]); 18 return t; 19 } 20 21 int main() 22 { 23 scanf("%d%d%lld",&n,&m,&s),mn=1000003; 24 for (i=1;i<=n;i++) scanf("%d%d",&w[i],&v[i]),mx=max(mx,w[i]),mn=min(mn,w[i]); 25 for (i=1;i<=m;i++) scanf("%d%d",&l[i],&r[i]); 26 for (h=mn,t=++mx;h<t;) 27 { 28 mid=h+t>>1; 29 if (cal(mid)>s) h=mid+1; 30 else t=mid,k=mid; 31 } 32 if (cal(h)-s<cal(k)-s) k=h; 33 printf("%lld\n",abs(min(s-cal(k),cal(k-1)-s))); 34 return 0; 35 }
[NOIP2011]聪明的质监员 题解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。