70分不知所措,求助

P1314 [NOIP2011 提高组] 聪明的质监员

GameFreak @ 2022-07-16 14:34:14

我思路就是二分W+前缀和作判定,但死活不对,WA了4,7,9,11,12,18,求看

评测记录

#include<bits/stdc++.h>
using namespace std;
long long Min(long long x,long long y){
    return x<y?x:y;
}
long long Max(long long x,long long y){
    return x>y?x:y;
}
long long Abs(long long x){
    return x>0?x:-x;
}
long long w[200001],v[200001];
long long l[200001],r[200001];
long long W[200001],V[200001];
long long s;
long long n,m;
long long calc(long long x){
    for(int i=1;i<=n;i++)
        if(w[i]>=x) W[i]=W[i-1]+1,V[i]=V[i-1]+v[i];
        else W[i]=W[i-1],V[i]=V[i-1];
    long long ret=0;
    for(int i=1;i<=m;i++) ret+=(W[r[i]]-W[l[i]-1])*(V[r[i]]-V[l[i]-1]);
    return ret;
}
int main(){
    int L=0,R=-0x3f3f3f3f;
    scanf("%d%d%lld",&n,&m,&s);
    for(long long i=1;i<=n;i++){
        scanf("%lld%lld",&w[i],&v[i]);
        R=Max(R,w[i]);
    }
    for(long long i=1;i<=m;i++) scanf("%lld%lld",&l[i],&r[i]);
    long long ans=0x3f3f3f3f;
    R++;
    while(L<R){
        long long mid=(L+R)>>1;
        long long now=calc(mid);
        if(now>=s) L=mid+1,ans=now;
        else R=mid;
    }
    if(ans==s) printf("0");
    else printf("%lld",Min(ans,Abs(s-calc(L-1))));
    return 0;
}

by Locix_Elaina_Celome @ 2022-07-16 16:37:44

@LQ2024 你在二分过程中取个最小答案


by Locix_Elaina_Celome @ 2022-07-16 16:38:50

int ans=0;
while(L<R){
        long long mid=(L+R)>>1;
        long long now=calc(mid);
        if(now>=s) L=mid+1,ans=now;
        else R=mid;
        ans=min(ans,abs(now-s));
    }

by Locix_Elaina_Celome @ 2022-07-16 16:39:11

最后输出ans


by GameFreak @ 2022-07-16 22:17:06

@fcy_nimas 解决了,谢谢!


|