codeVS1138 聪明的质监员

二分水题。为什么要写这道题呢,因为要辨明long long的读入与输出。

经过俩天的调试(我还以为我代码写错了)。。。

发现codeVS,tyvj输入输出用lld,vijos用I64d

这篇题解除了我应该也不会有人看见。。所以肯定还会有大量人入坑。

呜呼哀哉。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn = 200000 + 10;
const int maxw = 2000000;

int n,m;
long long s[maxn],t[maxn];
int w[maxn],v[maxn];
int L[maxn],R[maxn];
int l,r,mid;
long long res,res2,S1;

long long solve() {
    t[0]=0; s[0]=0; res=0LL;
    for(int i=1;i<=n;i++)
        if(w[i]>=mid) {
            t[i]=t[i-1]+1;
            s[i]=(long long)s[i-1]+v[i];
        }
        else {
            t[i]=t[i-1];
            s[i]=s[i-1];
        }
    for(int i=1;i<=m;i++) 
        res += (t[R[i]]-t[L[i]-1])*(s[R[i]]-s[L[i]-1]);
    return res;
}

int main() {
    scanf("%d%d%lld",&n,&m,&S1);
    l=0;r=maxw;
    for(int i=1;i<=n;i++) {
        scanf("%d%d",&w[i],&v[i]);
        r=max(r,w[i]);
    }
    for(int i=1;i<=m;i++) scanf("%d%d",&L[i],&R[i]);
    r++;
    res2=10000000000000000LL;
    while(l<r) {
        mid=(l+r)>>1;
        long long res = solve();
        res2=min(res2,abs(res-S1));
        if(res>S1) l=mid+1;
        else r=mid;
    }
    for(int i=l;i<=r;i++) solve();
    cout<<res2<<'
';
    return 0;
}

原文地址:https://www.cnblogs.com/invoid/p/5486996.html