MnZn 55pts求助

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

OK咯莫名其妙 @ 2021-11-15 15:38:55


#include<bits/stdc++.h>
#define int long long 
using namespace std;
int maxx=-2e9;
struct node{
    int w,v;
}a[200005];
int s[200005];
int cnt[200005];
int n,m,y;
int flag=0;
int lef[200005],righ[200005];
int check(int k){
    memset(s,0,sizeof(s));
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=n;i++)
    {
        if(a[i].v>=k){
            s[i]=s[i-1]+a[i].w;
            cnt[i]=cnt[i-1]+1;
        }
        else
        {
            s[i]=s[i-1];
            cnt[i]=cnt[i-1];
        }
    }
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        sum+=(cnt[righ[i]]-cnt[lef[i]-1])*(s[righ[i]]-s[lef[i]-1]);
    }
    if(sum>y)return true;
    if(sum<y)return false;
    if(sum==0){
        flag=1;
        return true;
    }
}
signed main(){
//  freopen("P1314_4.in","r",stdin);
    cin>>n>>m>>y;
    for(int i=1;i<=n;i++){
        cin>>a[i].v>>a[i].w;
        maxx=max(maxx,a[i].v);  
    }
    for(int i=1;i<=m;i++)
    {
        cin>>lef[i]>>righ[i];
    }
    int l=0,r=maxx;
    while(l<=r){
        int mid=(l+r+1)>>1;
        if(flag==1){
            cout<<0<<endl;
            return 0;
        }
        else
        {
            if(check(mid))l=mid+1;
            else
            r=mid-1;
        }
    }
    int ans=0;
    l=l-1;
    for(int i=1;i<=m;i++)
    {
        int num=0;
        int tmp=0;
        for(int j=lef[i];j<=righ[i];j++)
        {
            if(a[j].v>=l){
                num++;
                tmp+=a[j].w;
            }
            else
            continue;
        }
        ans+=num*tmp;
    }
    cout<<ans-y<<endl;
    return 0;
}

by 漠寒 @ 2021-11-15 15:50:34

@OK咯莫名其妙 可能最后用 l-1 更新答案的问题,可以在 check 内部进行最终答案的更新,改后的这份代码已过。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int maxx=-2e9;
struct node{
    int w,v;
}a[200005];
int s[200005];
int cnt[200005];
int n,m,y;
int flag=0;
int lef[200005],righ[200005];
int ans=1e18;
int check(int k){
    memset(s,0,sizeof(s));
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=n;i++)
    {
        if(a[i].v>=k){
            s[i]=s[i-1]+a[i].w;
            cnt[i]=cnt[i-1]+1;
        }
        else
        {
            s[i]=s[i-1];
            cnt[i]=cnt[i-1];
        }
    }
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        sum+=(cnt[righ[i]]-cnt[lef[i]-1])*(s[righ[i]]-s[lef[i]-1]);
    }
    ans=min(ans,abs(sum-y));
    if(sum>y)return true;
    if(sum<y)return false;
}
signed main(){
    cin>>n>>m>>y;
    for(int i=1;i<=n;i++){
        cin>>a[i].v>>a[i].w;
        maxx=max(maxx,a[i].v);  
    }
    for(int i=1;i<=m;i++)
    {
        cin>>lef[i]>>righ[i];
    }
    int l=0,r=maxx;
    while(l<=r){
        int mid=(l+r+1)>>1;
        if(flag==1){
            cout<<0<<endl;
            return 0;
        }
        else
        {
            if(check(mid))l=mid+1;
            else
            r=mid-1;
        }
    }
    cout<<ans<<endl;
    return 0;
}

by OK咯莫名其妙 @ 2021-11-15 15:55:07

感谢大佬


|