90分代码求挑错

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

diltraser @ 2018-08-28 14:20:41

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;

int M=0;
int sum[200010];
int num[200010];
int w[200010];
int v[200010];
int left[200010];
int right[200010];
int n,m;
ll s;

void find(int x){
    int i;
    for(i=1;i<=n;i++){
        num[i]=num[i-1];
        sum[i]=sum[i-1];
        if(w[i]>=x){
            num[i]++;
            sum[i]+=v[i];
        }
    }
}

ll check(int x){
    int i;
    find(x);
    ll ans=0;
    for(i=1;i<=m;i++)
            ans+=(num[right[i]]-num[left[i]-1])
            *(sum[right[i]]-sum[left[i]-1]);
    return llabs(s-ans);
}

ll search(int minn,int maxn){
    ll ans=0;
    while(maxn-minn>1){
        int mid=minn+(maxn-minn)/2;
        find(mid);
        ans=0;
        int i;
        for(i=1;i<=m;i++)
            ans+=(num[right[i]]-num[left[i]-1])
            *(sum[right[i]]-sum[left[i]-1]);
        if(ans<s)
            maxn=mid;
        if(ans==s)return 0;
        if(ans>s)minn=mid;
    }
    return min(check(maxn),check(minn));
}

int main(){
    scanf("%d%d%lld",&n,&m,&s);
    int i;
    for(i=1;i<=n;i++){
        scanf("%d%d",&w[i],&v[i]);
        M=max(M,w[i]);
    }
    for(i=1;i<=m;i++)
        scanf("%d%d",&left[i],&right[i]);
    printf("%lld",search(1,M));
    return 0;
}

by 我没有小白 @ 2018-10-09 21:51:32

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#define LL long long
using namespace std;
const int N = 200010;
int n,q,w[N],v[N],l=2000005,r,L[N],R[N];
LL sumw[N],sumv[N];
LL s,minn=9999999999999999ll;
LL _abs(LL x) {
    return x>0?x:-x;
}
LL min(LL x,LL y) {
    return x<y?x:y;
}
LL max(LL x,LL y){
    return x>y?x:y;
}
bool judge(int mid) {
    memset(sumw,0,sizeof(sumw));
    memset(sumv,0,sizeof(sumv));
    for(int i=1; i<=n; i++) {
        if(w[i]>=mid) sumw[i]=sumw[i-1]+1,sumv[i]=sumv[i-1]+v[i];
        else sumw[i]=sumw[i-1],sumv[i]=sumv[i-1];
    }
    LL ans=0;
    for(int i=1; i<=q; i++) {
        ans+=(sumw[R[i]]-sumw[L[i]-1])*(sumv[R[i]]-sumv[L[i]-1]);
    }
    minn=min(minn,_abs(ans-s));
    if(ans>s)return true;
    else return false;
}
int main() {
//  freopen("a.in","r",stdin);
    scanf("%d%d%lld",&n,&q,&s);
    for(int i=1; i<=n; i++) scanf("%d%d",&w[i],&v[i]),l=min(l,w[i]),r=max(r,w[i]);
    for(int i=1; i<=q; i++) scanf("%d%d",&L[i],&R[i]);
    while(l<=r) {
        int m=(l+r)>>1;
        if(judge(m)) l=m+1;
        else r=m-1;
    }
    printf("%lld",minn);
}

90同求


by 迦娜酱 @ 2018-10-12 16:13:14

#include<bits/stdc++.h>
using namespace std;
int sumg[300000];
int sumv[300000];
int va[300000];
int w[300000];
int mxva;
unsigned long long S;
int n , m;
int miva = 500000;
unsigned long long ans = 7878797000979087987;
struct qus{
    int l , r;
}qs[300000];
inline void get_sfx( int lim ){
    for( register int i = 1 ; i <= n ; ++i ){
        sumg[i] = sumg[i - 1];
        sumv[i] = sumv[i - 1]; 
        if( w[i] >= lim ){
            ++sumg[i];
            sumv[i] += va[i];
        }
    }
}
inline long long check( int lim ){
    get_sfx( lim );
    unsigned long long quk = 0;
    for( register int i = 1; i <= m ; ++i ){
        long long pl = sumg[qs[i].r] - sumg[qs[i].l - 1];
        long long lp = sumv[qs[i].r] - sumv[qs[i].l - 1];
        quk += pl * lp;
    }
    return quk;
}
void merge( ){
    while( mxva > miva ){
        int mid = (mxva + miva)>>1;
        unsigned long long temp = check( mid );
        if( temp > S ) miva = mid + 1;
        else if( temp == S ) {ans = 0;return;}
        else mxva = mid;
        unsigned long long ttemp = max( S , temp ) - min( S , temp );
        ans = min( ans , ttemp );
    }
}
int main(){
    scanf( "%d%d%lld" ,&n ,&m ,&S );
    for( register int i = 1; i <= n ; ++i ){
        scanf( "%d%d" , &w[i] ,&va[i] );
        miva = min( w[i] , miva );
        mxva = max( w[i] , mxva );
    }
    for( register int i = 1; i <= m ; ++ i ){
        scanf( "%d%d" ,&qs[i].l ,&qs[i].r );
    }
    merge();
    cout<<ans;
}
/*
10 10 1475400
23954 25180
18805 2701
17195 5663
7044 13659
8139 30927
19774 25516
7472 4572
5999 6166
1185 13621
10414 26521
2 10
4 7
5 8
1 6
2 7
1 3
2 7
3 4
1 6
1 10
*/

MMP就我一个95求吗qwq


by 迦娜酱 @ 2018-10-12 16:58:24

明白叻qwq

左右端点不能直接赋成Wi的最大最小值

而是要比Wi的最大值大一点

比Wi的最小值小一点

qwqwqwqwqwqwqwqwq


|