2017.4.24 聪明的质检员 思考记录

来源:互联网 发布:算法导论是c语言 编辑:程序博客网 时间:2024/06/07 16:48

        被式子卡了一会、、

           只要Σ没有括号,就只累加紧跟着的一个!!!!    

       

        虽然标有提高+ 省选-的难度标签,但个人认为只能是普及+

        除了第20个点卡取max  上限 但二分很显然啊 、


      虽然   被大于等于mid的所有区间和卡了一下、、 

          但求动态前缀和的方法应该不难想到的

            因为对于log,你一次的计算只能是n的

            而题目的式子显然是前缀和的标准条件、、(连续+求和)

             所以扫一遍序列,在求前缀和的时候不加那些小于w[i]不就行了、、、


         检验的时候就围绕绝对值最小展开就行了   >0提高下限    <0降低上限

                     

码:

#include<iostream>#include<cstdio>using namespace std;#define N 200002 long long n,m,s,i,ll[N],rr[N],v[N],l,r=1e6+1,mid,ans=1e14+9,w[N],qsum[N],he,qsum2[N];int main(){scanf("%lld%lld%lld",&n,&m,&s);for(i=1;i<=n;i++){scanf("%lld%lld",&w[i],&v[i]);}for(i=1;i<=m;i++){scanf("%lld%lld",&ll[i],&rr[i]);}l=0;while(l<r){mid=(l+r)>>1;he=0;for(i=1;i<=n;i++){if(w[i]>=mid)qsum[i]=qsum[i-1]+v[i],qsum2[i]=qsum2[i-1]+1;else qsum[i]=qsum[i-1],qsum2[i]=qsum2[i-1];}for(i=1;i<=m;i++){he+=(qsum[rr[i]]-qsum[ll[i]-1])*(qsum2[rr[i]]-qsum2[ll[i]-1]);}he-=s;if(he<0){ans=min(ans,-he); r=mid;}else  {  ans=min(ans,he); l=mid+1;    }}printf("%lld",ans);}


0 0