题解 P1314 【聪明的质监员】

teafrogsf

2017-09-12 21:41:02

Solution

## 博客即是洛谷blog。 本题是一个比较明显的二分题,显然可以看出来这个标准值S是可以二分的,之后如果暴力O(nmlog1e6)就是50分。 但我们显然不用暴力,这里我们可以先预扫一遍数组,并用前缀和存w和v,之后再一个O(m)暴力判断就可以了。 和大于标准时加大l以加大mid,小于时减少r。 **并一定要注意l和r的初始大小**,l为所有值中最小-1~~虽然貌似不减也可以过~~,r为最大值+1。 ```cpp #include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #define neko 300010 #define f(i,a,b) for(register int i=a;i<=b;++i) typedef long long ll; struct node { int l,r; }q[neko]; int n,m,l,r,mid,minn=1000000000,maxn,w[neko],c[neko]; ll stdd,sum,ans=1e13,v[neko],s[neko]; int main() { int i,j; scanf("%d%d%lld",&n,&m,&stdd); f(i,1,n)scanf("%d%lld",&w[i],&v[i]),minn=std::min(minn,w[i]),maxn=std::max(maxn,w[i]); l=minn-1,r=maxn+1; f(i,1,m)scanf("%d%d",&q[i].l,&q[i].r); while(l<r) { mid=(l+r)>>1,sum=0,memset(c,0,sizeof(c)),memset(s,0,sizeof(s)); f(i,1,n) { if(w[i]>=mid)c[i]=c[i-1]+1,s[i]=s[i-1]+v[i]; else c[i]=c[i-1],s[i]=s[i-1]; } f(i,1,m)sum+=(c[q[i].r]-c[q[i].l-1])*(s[q[i].r]-s[q[i].l-1]); //printf("%d %d %d %d\n",l,r,mid,sum); if(llabs(stdd-sum)<ans)ans=llabs(stdd-sum); if(sum>stdd)l=mid+1; else r=mid; }printf("%lld\n",ans); return 0; } O(m(n)log1e6)。 ```