标签:shu inf ring pen iter inpu 元素 pre class
1
2
2
2
2
正解:$link-cut tree+set$
这题我能说什么。。考场上没想到,然而考后就想出来了。。
其实这题是一道大水题吧。。其实连$LCT$都不要用,直接线段树维护就行了。。
我们可以观察得到:插入结点时一定是插到它的前驱或后继中深度更深的那个下面。
单旋最值其实就是把最值抽出来,与原来的根相连,然后再把它的子树与它原来的父亲相连。删除操作类似,还简单一些。。
然后我们直接用$LCT$维护$spaly$。插入,单旋,删除的时候各种$link$,$cut$就行了,顺便再开两个数组维护一下原树的父子关系。
同时我们要查询前驱,后继,最小值,最大值,这个用$set$就能很方便地解决。
每次查询深度,就是$makeroot$一下树根,然后$access$并$splay$当前点,直接查询$splay$中子树大小就行了。
注意细节:如果单旋的时候这个点已经是根就不要$link$,$cut$了。这个地方坑了我好久。。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define inf (1<<30) 15 #define N (100010) 16 #define ls (x<<1) 17 #define rs (x<<1|1) 18 #define il inline 19 #define RG register 20 #define ll long long 21 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 22 23 using namespace std; 24 25 set <int> tr; 26 set <int>::iterator r; 27 28 struct data{ int c,k; }q[N]; 29 30 int hsh[N],rev[N],sz[N],st[N],fa[N],ch[N][2],f[N],c[N][2],m,rt,cnt,tot; 31 32 il int gi(){ 33 RG int x=0,q=1; RG char ch=getchar(); 34 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 35 if (ch==‘-‘) q=-1,ch=getchar(); 36 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 37 return q*x; 38 } 39 40 il int isroot(RG int x){ 41 return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; 42 } 43 44 il void pushdown(RG int x){ 45 rev[x]=0,rev[ch[x][0]]^=1,rev[ch[x][1]]^=1; 46 swap(ch[x][0],ch[x][1]); return; 47 } 48 49 il void pushup(RG int x){ 50 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; return; 51 } 52 53 il void rotate(RG int x){ 54 RG int y=fa[x],z=fa[y],k=ch[y][0]==x; 55 if (!isroot(y)) ch[z][ch[z][1]==y]=x; 56 fa[x]=z,ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y; 57 ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return; 58 } 59 60 il void splay(RG int x){ 61 RG int top=0; st[++top]=x; 62 for (RG int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; 63 for (RG int i=top;i;--i) if (rev[st[i]]) pushdown(st[i]); 64 while (!isroot(x)){ 65 RG int y=fa[x],z=fa[y]; 66 if (!isroot(y)){ 67 if ((ch[z][0]==y)^(ch[y][0]==x)) rotate(x); 68 else rotate(y); 69 } 70 rotate(x); 71 } 72 return; 73 } 74 75 il void access(RG int x){ 76 RG int t=0; 77 while (x){ 78 splay(x),ch[x][1]=t; 79 pushup(x),t=x,x=fa[x]; 80 } 81 return; 82 } 83 84 il void makeroot(RG int x){ 85 access(x),splay(x),rev[x]^=1; return; 86 } 87 88 il void link(RG int x,RG int y){ 89 if (!x || !y || x==y) return; 90 makeroot(x),fa[x]=y; return; 91 } 92 93 il void cut(RG int x,RG int y){ 94 if (!x || !y || x==y) return; 95 makeroot(x),access(y),splay(y); 96 fa[x]=ch[y][0]=0,pushup(y); return; 97 } 98 99 il int query(RG int x){ 100 makeroot(rt),access(x),splay(x); 101 return sz[x]; 102 } 103 104 il void update1(RG int x,RG int k){ 105 RG int y=f[x],z=c[x][k]; 106 c[x][k]=rt,f[rt]=x,f[x]=0; 107 c[y][k^1]=z,f[z]=y; return; 108 } 109 110 il void update2(RG int x,RG int k){ 111 RG int y=f[x],z=c[x][k]; if (x==rt) rt=z; 112 c[y][k^1]=z,f[z]=y,c[x][k]=f[x]=0; return; 113 } 114 115 il void work(){ 116 m=gi(),tr.insert(-inf),tr.insert(inf); 117 for (RG int i=1;i<=m;++i){ 118 q[i].c=gi(),sz[i]=1; 119 if (q[i].c==1) q[i].k=gi(),hsh[++tot]=q[i].k; 120 } 121 sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1; 122 for (RG int i=1;i<=m;++i){ 123 if (q[i].c==1){ 124 q[i].k=lower_bound(hsh+1,hsh+tot+1,q[i].k)-hsh; 125 if (!cnt) tr.insert(rt=q[i].k),++cnt,puts("1"); else{ 126 r=tr.upper_bound(q[i].k); RG int nxt=*r,x=0,d=0,k; --r; RG int pre=*r; 127 if (pre!=-inf){ k=query(pre); if (d<k) x=pre,d=k; } 128 if (nxt!=inf){ k=query(nxt); if (d<k) x=nxt,d=k; } 129 f[q[i].k]=x,c[x][x<q[i].k]=q[i].k,link(x,q[i].k); 130 ++cnt,tr.insert(q[i].k),printf("%d\n",d+1); 131 } 132 } 133 if (q[i].c==2){ 134 if (cnt==1) puts("1"); else{ 135 r=tr.begin(),++r; RG int x=*r,y=f[x],z=c[x][1],k=query(x); 136 if (x!=rt) cut(x,y),cut(x,z),link(x,rt),link(y,z),update1(x,1),rt=x; 137 printf("%d\n",k); 138 } 139 } 140 if (q[i].c==3){ 141 if (cnt==1) puts("1"); else{ 142 r=tr.end(),--r,--r; RG int x=*r,y=f[x],z=c[x][0],k=query(x); 143 if (x!=rt) cut(x,y),cut(x,z),link(x,rt),link(y,z),update1(x,0),rt=x; 144 printf("%d\n",k); 145 } 146 } 147 if (q[i].c==4){ 148 if (cnt==1) puts("1"),tr.erase(tr.find(rt)),rt=0,--cnt; else{ 149 r=tr.begin(),++r; RG int x=*r,y=f[x],z=c[x][1],k=query(x); 150 tr.erase(tr.find(x)),--cnt,cut(x,y),cut(x,z),link(y,z); 151 update2(x,1),printf("%d\n",k); 152 } 153 } 154 if (q[i].c==5){ 155 if (cnt==1) puts("1"),tr.erase(tr.find(rt)),rt=0,--cnt; else{ 156 r=tr.end(),--r,--r; RG int x=*r,y=f[x],z=c[x][0],k=query(x); 157 tr.erase(tr.find(x)),--cnt,cut(x,y),cut(x,z),link(y,z); 158 update2(x,0),printf("%d\n",k); 159 } 160 } 161 } 162 return; 163 } 164 165 int main(){ 166 File("splay"); 167 work(); 168 return 0; 169 }
标签:shu inf ring pen iter inpu 元素 pre class
原文地址:http://www.cnblogs.com/wfj2048/p/6767775.html