[BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)

    xiaoxiao2021-03-25  159

    题目:

    我是超链接

    题解:

    那什么.....今天真是有毒,splay都是细节没有考虑好,如果这个人本来就达不到minn,何必让他加入公司呢......

    没有写区间操作,直接把minn处理了,好像简单一些呢

    代码:

    #include <cstdio> #define N 100000 using namespace std; int f[N+5],cnt[N+5],size[N+5],ch[N+5][2],key[N+5]; int sz=0,root=0,ff=0,e=0,tot; void clear(int x){size[x]=cnt[x]=key[x]=f[x]=0;ch[x][0]=ch[x][1]=0;} int get(int x){return ch[f[x]][1]==x;} int pre() { int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now; } int next() { int now=ch[root][1]; while (ch[now][0]) now=ch[now][0]; return now; } void updata(int x) { if (x) { size[x]=cnt[x]; if (ch[x][0]) size[x]+=size[ch[x][0]]; if (ch[x][1]) size[x]+=size[ch[x][1]]; } } void rotate(int x) { int old=f[x],oldf=f[old],which=get(x); ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old; ch[x][which^1]=old; f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ch[oldf][1]==old]=x; updata(old); updata(x); } void splay(int x) { for (int fa;fa=f[x];rotate(x)) if (f[fa]) rotate((get(x)==get(fa))?fa:x); root=x; } int findx(int x) { int now=root; while (1) { if(ch[now][0] && x<=size[ch[now][0]]) now=ch[now][0]; else { int tmp=(ch[now][0]?size[ch[now][0]]:0)+cnt[now]; if (x<=tmp) return key[now]; x-=tmp; now=ch[now][1]; } } } int find(int x) { int ans=0,now=root; while (1) { if (x<key[now]) now=ch[now][0]; else { ans+=(ch[now][0]?size[ch[now][0]]:0); if (x==key[now]) { splay(now); return ans+1; } ans+=cnt[now]; now=ch[now][1]; } } } void insert(int x) { if (root==0) { sz++;root=sz;size[sz]=cnt[sz]=1;key[sz]=x;f[sz]=0;ch[sz][0]=ch[sz][1]=0;return; } int now=root,fa=0; while (1) { if (x==key[now]) { cnt[now]++; updata(now); updata(fa); splay(now); return; } fa=now; now=ch[now][key[now]<x]; if (now==0) { sz++; size[sz]=cnt[sz]=1;key[sz]=x;f[sz]=fa;ch[sz][0]=ch[sz][1]=0; ch[fa][key[fa]<x]=sz; updata(fa); splay(sz); return; } } } void del(int x) { int whatever=find(x); if (cnt[root]>1) { cnt[root]--; updata(root); return; } if (!ch[root][0] && !ch[root][1]) { clear(root); root=0; return; } if (!ch[root][0]) { int oldroot=root; root=ch[root][1]; f[root]=0; clear(oldroot); return; } else if (!ch[root][1]) { int oldroot=root; root=ch[root][0]; f[root]=0; clear(oldroot); return; } int leftbig=pre(),oldroot=root; splay(leftbig); f[ch[oldroot][1]]=root; ch[root][1]=ch[oldroot][1]; clear(oldroot); updata(root); return; } int main() { int n,minn,i; scanf("%d%d",&n,&minn); for (i=1;i<=n;i++) { char chh;int x; scanf("\n%c%d",&chh,&x); switch(chh) { case 'I':if (x<minn) continue; insert(x-e); tot++; break; case 'A':e+=x; break; case 'S':e-=x; insert(minn-e); ff+=size[ch[root][0]]; ch[root][0]=0; del(minn-e); break; case 'F':if (tot-ff<x) printf("-1\n");else printf("%d\n",findx(tot-ff-x+1)+e); break; } } printf("%d",ff); }

    转载请注明原文地址: https://ju.6miu.com/read-2133.html

    最新回复(0)