Luogu3721[AH2017/HNOI2017]單旋
阿新 • • 發佈:2019-03-13
tor lse iterator using www ++ pac class fin
Luogu3721[AH2017/HNOI2017]單旋
題面:洛谷
解析:
考慮模擬題中所述單旋過程,會發現對於一次旋轉的操作,就是把它的兒子和父親接起來,把它置為當前根的父親,成為新根,而對於插入操作,開一個\(set\),查詢前驅後繼即可,代碼細節較多。
代碼
// luogu-judger-enable-o2 #include<set> #include<map> #include<cstdio> #include<cstring> #define I inline void #define lc c[x][0] #define rc c[x][1] #define N 100005 using namespace std; int m; set<int> Set; map<int,int> mp; int c[N][2],f[N],r[N],sz[N]; inline int In(){ char c=getchar(); int x=0,ft=1; for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; return x*ft; } inline bool nrt(int x){ return c[f[x]][0]==x||c[f[x]][1]==x; } I PushUp(int x){ sz[x]=sz[lc]+sz[rc]+1; } I PushDown(int x){ if(r[x]){ swap(lc,rc); r[lc]^=1; r[rc]^=1; r[x]=0; } } I rotate(int x){ int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k]; if(nrt(y)) c[z][c[z][1]==y]=x; c[x][!k]=y; c[y][k]=w; if(w) f[w]=y; f[y]=x; f[x]=z; PushUp(y); } I PushAll(int x){ if(nrt(x)) PushAll(f[x]); PushDown(x); } I splay(int x){ PushAll(x); int y; while(nrt(x)){ if(nrt(y=f[x])) rotate((c[f[y]][1]==y)^(c[y][1]==x)?x:y); rotate(x); } PushUp(x); } I access(int x){ for(int y=0;x;x=f[y=x]) splay(x),rc=y,PushUp(x); } I makeroot(int x){ access(x); splay(x); r[x]^=1; } I split(int x,int y){ makeroot(x); access(y); splay(y); } I link(int x,int y){ makeroot(x); f[x]=y; } I cut(int x,int y){ split(x,y); f[x]=c[y][0]=0; PushUp(y); } int rt,tot=0,fa[N],ls[N],rs[N]; I Splay_insert(int x){ int p=++tot; mp[x]=p; if(Set.empty()){ Set.insert(x); rt=p; puts("1"); return; } set<int> :: iterator it=Set.upper_bound(x); if(it==Set.end()||ls[mp[*it]]){ --it; int k=mp[*it]; fa[p]=k; rs[k]=p; link(p,k); } else{ int k=mp[*it]; fa[p]=k; ls[k]=p; link(p,k); } Set.insert(x); split(p,rt); printf("%d\n",sz[rt]); } I Splay_min(){ set<int> :: iterator it=Set.begin(); int p=mp[*it]; if(p==rt){ puts("1"); return; } split(p,rt); printf("%d\n",sz[rt]); cut(p,fa[p]); if(rs[p]) cut(p,rs[p]),link(rs[p],fa[p]); ls[fa[p]]=rs[p]; if(rs[p]) fa[rs[p]]=fa[p]; link(p,rt); fa[rt]=p; fa[p]=0; rs[p]=rt; rt=p; } I Splay_max(){ set<int> :: iterator it=--Set.end(); int p=mp[*it]; if(p==rt){ puts("1"); return; } split(p,rt); printf("%d\n",sz[rt]); cut(p,fa[p]); if(ls[p]) cut(p,ls[p]),link(ls[p],fa[p]); rs[fa[p]]=ls[p]; if(ls[p]) fa[ls[p]]=fa[p]; link(p,rt); fa[rt]=p; fa[p]=0; ls[p]=rt; rt=p; } I Del_min(){ set<int> :: iterator it=Set.begin(); int p=mp[*it]; if(p==rt){ if(rs[rt]) cut(rt,rs[rt]); rt=rs[rt]; fa[rt]=0; Set.erase(it); puts("1"); return; } split(p,rt); printf("%d\n",sz[rt]); cut(p,fa[p]); if(rs[p]) cut(p,rs[p]),link(rs[p],fa[p]); ls[fa[p]]=rs[p]; if(rs[p]) fa[rs[p]]=fa[p]; Set.erase(it); } I Del_max(){ set<int> :: iterator it=--Set.end(); int p=mp[*it]; if(p==rt){ if(ls[rt]) cut(rt,ls[rt]); rt=ls[rt]; fa[rt]=0; Set.erase(it); puts("1"); return; } split(p,rt); printf("%d\n",sz[rt]); cut(p,fa[p]); if(ls[p]) cut(p,ls[p]),link(ls[p],fa[p]); rs[fa[p]]=ls[p]; if(ls[p]) fa[ls[p]]=fa[p]; Set.erase(it); } int main(){ m=In(); for(int i=1,op,key;i<=m;++i){ op=In(); if(op==1) key=In(),Splay_insert(key); if(op==2) Splay_min(); if(op==3) Splay_max(); if(op==4) Del_min(); if(op==5) Del_max(); } return 0; }
Luogu3721[AH2017/HNOI2017]單旋