【bzoj1503】 NOI2004—郁闷的出纳员
http://www.lydsy.com/JudgeOnline/problem.php?id=1503 (题目链接)
题意
要求维护4种操作:插入一个数,将所有数加上k,将所有数减去k,删去数值小于k的数并计算个数。
Solution
splay。今天考试的时候询问时忘记下传标记了fuck dog
代码
// bzoj1503 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=500010; int tr[maxn][2],size[maxn],val[maxn],sum[maxn],fa[maxn],tag[maxn]; int rt,cnt,S,n,ming,tot; void update(int k) { int l=tr[k][0],r=tr[k][1]; size[k]=size[l]+size[r]+sum[k]; } void rotate(int x,int &k) { int y=fa[x],z=fa[y],l,r; l=tr[y][1]==x;r=l^1; if (k==y) k=x; else tr[z][tr[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[tr[x][r]]=y; tr[y][l]=tr[x][r];tr[x][r]=y; update(y);update(x); } void splay(int x,int &k) { while (x!=k) { int y=fa[x],z=fa[y]; if (y!=k) { if ((tr[z][0]==y) ^ (tr[y][0]==x)) rotate(x,k); else rotate(y,k); } rotate(x,k); } } void pushdown(int k) { val[tr[k][1]]+=tag[k];tag[tr[k][1]]+=tag[k]; val[tr[k][0]]+=tag[k];tag[tr[k][0]]+=tag[k]; tag[k]=0; } void insert(int x) { int k=rt,f=0; while (k) { if (tag[k]) pushdown(k);f=k; if (x<val[k]) k=tr[k][0]; else if (x>val[k]) k=tr[k][1]; else {sum[k]++;size[k]++;S++;splay(k,rt);return;} } S++; fa[++cnt]=f;sum[cnt]=size[cnt]=1;val[cnt]=x;tr[f][x>val[f]]=cnt; splay(cnt,rt); } int find(int x,int k) { if (tag[k]) pushdown(k); int ans=0; while (k) { if (tag[k]) pushdown(k); if (x==val[k]) return k; if (x<val[k]) ans=k,k=tr[k][0]; else k=tr[k][1]; } return ans; } void modify(int k) { val[rt]+=k,tag[rt]+=k; if (k<0) { int x=find(ming,rt); splay(x,rt); tot+=size[tr[x][0]];S-=size[tr[x][0]];tr[x][0]=0; } } int query(int x,int k) { if (tag[k]) pushdown(k); int l=tr[k][0],r=tr[k][1]; if (x>=size[r]+1 && x<=size[r]+sum[k]) return k; else if (x<=size[r]) return query(x,r); else return query(x-size[r]-sum[k],l); } int main() { char ch[10];int k; tot=0; rt=cnt=1;val[1]=(1<<30); scanf("%d%d",&n,&ming); for (int i=1;i<=n;i++) { scanf("%s%d",ch,&k); if (ch[0]=='I') {if (k>=ming) insert(k);/*else tot++;*/} if (ch[0]=='A') modify(k); if (ch[0]=='S') modify(-k); if (ch[0]=='F') printf("%d\n",k>S ? -1 : val[query(k,rt)]); } printf("%d\n",tot); return 0; }
This passage is made by MashiroSky.