zoukankan      html  css  js  c++  java
  • P1314 聪明的质监员

    传送门

    看到最值的问题容易想到二分答案

    二分答案已经有一个 log 了

    考虑如何O(n) 求出每个区间和

    显然前缀和,O(n) 扫一遍然后对每个区间O(1)统计答案

    注意long long,然后就过了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e5+7;
    int n,m;
    int a[N],b[N],l[N],r[N];
    ll sum[N],ans,S;
    int tot[N];
    inline ll check(int mid)
    {
        ll res=0;
        for(int i=1;i<=n;i++)
        {
            sum[i]=sum[i-1]; tot[i]=tot[i-1];
            if(a[i]<mid) continue;
            sum[i]+=b[i]; tot[i]++;
        }
        for(int i=1;i<=m;i++) res+=1ll*(tot[r[i]]-tot[l[i]-1])*(sum[r[i]]-sum[l[i]-1]);
        return res;
    }
    int L,R,mid;
    int main()
    {
        n=read(); m=read(); scanf("%lld",&S);
        for(int i=1;i<=n;i++) a[i]=read(),b[i]=read();
        for(int i=1;i<=m;i++) l[i]=read(),r[i]=read();
        R=1e6+7; ans=S;
        while(L<=R)
        {
            mid=L+R>>1;
            ll res=check(mid);
            if(res<S) R=mid-1,ans=min(ans,S-res);
            else L=mid+1,ans=min(ans,res-S);
        }
        printf("%lld",ans);
        return 0;
    }

     

  • 相关阅读:
    Luogu 3119 [USACO15JAN]草鉴定Grass Cownoisseur
    Luogu 4514 上帝造题的七分钟
    Luogu 1484 种树
    Luogu【P2904】跨河(DP)
    Luogu【P2065】贪心的果农(DP)
    Luogu【P1725】琪露诺(单调队列,DP)
    二分图匹配
    单调队列
    Tarjan的强联通分量
    手写堆
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9887377.html
Copyright © 2011-2022 走看看