NOIP 2011聪明的质监员

数据范围 1~2的6次方

算法 n*log N

二分加前缀加法



#include<bits/stdc++.h>

typedef long long  ll;
const long long MAXN = 200005;
ll sum_d[MAXN],sum_v[MAXN],n,m,s,mx=0,ans=pow(2,31);
using namespace std;
struct node_1
{
long long w,v;
}ks[MAXN];
struct node_2
{
long long l,r;
}qj[MAXN];
void init() {
scanf("%lld%lld%lld",&n,&m,&s);
for(int i=1; i<=n; i++) {
scanf("%lld%lld",&ks[i].w,&ks[i].v) ;
mx=max(ks[i].w,mx);
}
mx++;
for(int j=1; j<=m; j++) {
scanf("%lld%lld",&qj[j].l,&qj[j].r);
}
}
inline ll cal(ll wn){
ll qh=0;
    memset(sum_d,0,sizeof(sum_d));
memset(sum_v,0,sizeof(sum_v));

for(int i=1;i<=n;i++){
sum_d[i]=sum_d[i-1];
sum_v[i]=sum_v[i-1];
if(ks[i].w>=wn){
++sum_d[i];
sum_v[i]+=ks[i].v;
}
}

for(int j=1;j<=m;j++){
qh+=(sum_d[qj[j].r] - sum_d[qj[j].l - 1]) * (sum_v[qj[j].r] - sum_v[qj[j].l - 1]);
}

return qh;
}
int main(){
init();
ll R=mx,L=0;
    while (R-L > 1) { // (l, r)
        ll mid = (L+R)/2, y = cal(mid);
ans =  min(ans, abs(y-s));
        if (y > s)
           L = mid;
        else if (y < s)  R= mid;
        
else
            break;
    }
printf("%lld",ans);
return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值