NOIP2011提高组 聪明的质检员
2016-08-01 12:02
337 查看
这道题很明显要用二分猜答案,猜w的值,再来check。这里我用的前缀和的方法来check,求出前i个大于w 的个数和价值和,然后枚举每一个区间,算就好了。
注:要注意用longlong(考试的时候我就是这个错了)。
具体程序如下:
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn=200005; struct shu { int w,v; }a[maxn]; struct data { int x,y,id; }b[maxn]; long long n,m,s,g[maxn][3]; long long read() { long long x=0,ok=0; char ch; ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); while((ch>='0'&&ch<='9')||ch=='-') { if(ch=='-') ok=1; else x=x*10+ch-'0'; ch=getchar(); } return ok==1?-x:x; } void init() { n=read(); m=read(); s=read(); for(int i=1;i<=n;i++) { a[i].w=read(); a[i].v=read(); } for(int j=1;j<=m;j++) { b[j].x=read(); b[j].y=read(); } } long long check(long long x) { long long ans=0; for(int i=1;i<=n;i++) { if(a[i].w>=x) { g[i][1]=g[i-1][1]+1; g[i][0]=g[i-1][0]+a[i].v; } else { g[i][1]=g[i-1][1]; g[i][0]=g[i-1][0]; } } for(int i=1;i<=m;i++) { long long x1=g[b[i].y][1]-g[b[i].x-1][1]; long long x2=g[b[i].y][0]-g[b[i].x-1][0]; ans+=x1*x2; } return ans; } int main() { //freopen("qc.in","r",stdin); //freopen("qc.out","w",stdout); init(); int x=0,y=1000000; long long ans=10000000000000000ll; while(x<=y) { int z=(x+y)/2; long long p=check(z); if(p>s) x=z+1; if(p<s) y=z-1; if(p==s) { printf("0"); return 0; } ans=min(ans,abs(p-s)); } cout<<ans; return 0; }
相关文章推荐
- NOIP提高组2011 聪明的质检员
- NOIP 2011 - 提高组 聪明的质检员 二分+前缀和 重庆一中高2018级竞赛班第六次测试 2016.7.31 Problem 2
- Noip 提高组 2011 Day2 T2 聪明的质检员 二分法
- NOIP2011提高组 聪明的质检员(重庆一中高2018级信息学竞赛测验6) 解题报告
- noip2011提高组——聪明的质检员
- NOIP2011提高组 聪明的质检员(二分答案)
- 【NOIP2011提高组】聪明的质检员
- 洛谷 1314||NOIP 2011 聪明的质检员 二分 解题报告
- [NOIP 2011] 聪明的质检员
- NOIP 2011 提高组 聪明的质监员
- NOIP2011提高组 聪明的质监员 -SilverN
- [NOIP2011提高组day2]-2-聪明的质监员
- 洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)
- NOIP2011 D2 T2 聪明的质检员
- [FT][1]NOIP 2011 聪明的质检员
- [NOIP2011提高组]聪明的质监员
- [NOIP 2011] 聪明的质检员:二分,前缀和
- 全国信息学奥林匹克联赛(NOIP2011)复赛 提高组 day2 T2 聪明的质监员
- 【noip2011提高组】 聪明的质监员 前缀和+二分
- NOIP2011提高组 聪明的质监员 -SilverN