CF1354D MultiSet(树状数组+二分)
题意:
有两种操作:一种是把一个元素加入到集合中,一种是删除集合中第k个元素,求解最后集合里的元素。
题解:
祖传的树状数组套二分,这种题可遇不可求,比赛时直接秒了,不太会出现这么裸的数据结构题了,,,
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+500; int n,q; int lowbit (int x) { return x&-x; } int a[maxn]; int c[maxn]; void update (int x,int val) { for (int i=x;i<maxn;i+=lowbit(i)) c[i]+=val; } int sum (int x) { int ans=0; for (int i=x;i;i-=lowbit(i)) ans+=c[i]; return ans; } int kth (int x,int k) { int l=x+1,r=maxn; int ans=-1; while (l<=r) { int mid=(l+r)>>1; if (sum(mid)-sum(x)>=k) r=mid-1,ans=mid; else l=mid+1; } return ans; } int main () { scanf("%d%d",&n,&q); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i]+=100; update(a[i],1); } for (int i=1;i<=q;i++) { int x; scanf("%d",&x); if (x<=0) { x=-x; int tt=kth(1,x); if (tt==-1) continue; update(tt,-1); } else { update(x+100,1); } } int f=0; for (int i=1;i<=n;i++) { if (sum(i+100)-sum(i+99)) { printf("%d\n",i); f=1; break; } } if (!f) { printf("0\n"); } }