天天看點

聰明的質檢員(二分答案)

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

typedef long long ll;

const int maxn=200010;

ll n,m,s,w[maxn],v[maxn],l[maxn],r[maxn],now[maxn],now1[maxn];

ll check(ll x){

    ll num=0,cnt=0;

    for(int i=1;i<=n;i++) now[i]=0;

    for(int i=1;i<=n;i++) now1[i]=0;

    for(int i=1;i<=n;i++){

        now[i]=now[i-1]; now1[i]=now1[i-1];

        if(w[i]>=x){

            ++now[i];

            now1[i]+=v[i];

        }

    }

    for(int i=1;i<=m;i++){

        num+=(now1[r[i]]-now1[l[i]-1])*(now[r[i]]-now[l[i]-1]);

    }

    return num;

}

inline ll read(){

    ll num=0,f=1; char ch=getchar();

    while(ch<'0'||ch>'9'){

        if(ch=='-') f=-1;

        ch=getchar();

    }

    while(ch>='0'&&ch<='9') num=num*10+ch-'0',ch=getchar();

    return num;

}

int main(){

    scanf("%lld%lld%lld",&n,&m,&s);

    for(int i=1;i<=n;i++){

        w[i]=read(),v[i]=read();

    }

    for(int i=1;i<=m;i++){

        l[i]=read(),r[i]=read();

    }

    ll l=0,r=1000000000000,ans=1000000000000;

    while(l<=r){

        ll mid=l+(r-l)/2,cur=check(mid);

        if(cur>s){

            l=mid+1;

            ans=min(ans,abs(cur-s));

        }

        else if(cur<s){

            r=mid-1;

            ans=min(ans,abs(cur-s));

        }

        else{

            ans=0; break;

        }

    }

    cout<<ans<<endl;

    return 0;

}