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; }