• 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;
    }

     

  • 相关阅读:
    Mybatis和Hibernate
    SpringMVC运行原理
    HTML中class属性里有多个属性值
    json对象(增加数据)
    Ajax请求
    <url-pattern>里的/和/*
    mysql忘记密码
    Eclipse无法正常连接mysql8.0.20
    a+1和&a+1
    可重入函数与不可重入函数
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9887377.html
Copyright © 2020-2023  润新知