首页 > 代码库 > Bzoj4378--Poi2015Logistyka

Bzoj4378--Poi2015Logistyka

主要被坑在了询问上(说的好像修改可以坑人一样

设已经超过s的数有k个。

如果k>=c那么显然可行

否则如果剩下的数的和>=(c-k)*s的话则有解,否则无解

简单证明一下 :

如果sum>=(c-k)*s,由于每个数都是小于s的,所以剩下数的个数>=(c-k)*s/(s-1)>(c-k),所以必然可以选出(c-k)个数。

选出一个数之和上式依然成立

如果sum<(c-k)*s,显然无解,根本不够取

代码 : (贴的

#include<iostream>  
#include<cstdio>  
#include<algorithm>  
#define ll long long  
#define N 1000005  
using namespace std;  
  
int n,m,cnt,a[N],x[N],y[N],z[N],num[N],hash[N];  
struct bit_node{  
    ll c[N];  
    void add(int x,int t){  
        for (; x<=cnt; x+=x&-x) c[x]+=t;  
    }  
    ll qry(int x){  
        ll t=0; for (; x; x-=x&-x) t+=c[x]; return t;  
    }  
}bit1,bit2;  
int read(){  
    int x=0; char ch=getchar();  
    while (ch<0 || ch>9) ch=getchar();  
    while (ch>=0 && ch<=9){ x=x*10+ch-0; ch=getchar(); }  
    return x;  
}  
int find(int x){  
    int l=1,r=cnt,mid;  
    while (l<r){  
        mid=(l+r)>>1;  
        if (hash[mid]<x) l=mid+1; else r=mid;  
    }  
    return l;  
}  
int main(){  
    n=read(); m=read(); int i,j; char ch;  
    for (i=1; i<=m; i++){  
        ch=getchar(); while (ch<A || ch>Z) ch=getchar();  
        x[i]=read(); y[i]=num[i]=read();  
        z[i]=(ch==U)?1:0;  
    }  
    sort(num+1,num+m+1); hash[cnt=1]=num[1];  
    for (i=2; i<=m; i++)  
        if (num[i]!=num[i-1]) hash[++cnt]=num[i];  
    for (i=1; i<=m; i++) y[i]=find(y[i]);  
    for (i=1; i<=m; i++) if (z[i]){  
        if (j=a[x[i]]){  
            bit1.add(j,-1); bit2.add(j,-hash[j]);  
        }  
        a[x[i]]=y[i];  
        bit1.add(y[i],1); bit2.add(y[i],hash[y[i]]);  
    } else puts(bit2.qry(y[i]-1)>=(x[i]-bit1.qry(cnt)+bit1.qry(y[i]-1))*hash[y[i]]?"TAK":"NIE");  
    return 0;  
}

 

Bzoj4378--Poi2015Logistyka