推荐一篇帖子
http://blog.csdn.net/lyhypacm/article/details/6734748
这题暴力不可行主要是因为这颗树可能极度不平衡,不能用并查集是不能路径压缩,这样时间复杂度是很高的。
可以用伸展树主要是因为它的伸展性,每次操作后可以通过伸展使这棵树更好的保持平衡。
这题还是值得记录一下的,从早上做到了晚上,
第一次错误,定义了全局的n以及局部的n使得取得结果不正确,以后还是统一习惯,要么写在全局要么写在局部。
第二次错误,vector初始化没有初始到0导致后面的数据跑不动,以后初始化的操作都从0开始。
第三次错误,debug了n久,建树的时候误把根节点的父亲节点写成了根,应该是0,自以为不会出错的地方也要认真检查。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<stack> 11 using namespace std; 12 #define N 100010 13 #define LL long long 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 int n,po[N]; 19 vector<int>ed[N]; 20 vector<int>dd; 21 22 struct splay_tree 23 { 24 int pre[N]; 25 int ch[N][2]; 26 int root,tot,num; 27 int key[N]; 28 // void dfs(int x) 29 // { 30 // if(x) 31 // { 32 // dfs(ch[x][0]); 33 // printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n", 34 // x,ch[x][0],ch[x][1],pre[x],size[x],key[x]); 35 // dfs(ch[x][1]); 36 // } 37 // } 38 // void debug() 39 // { 40 // printf("root:%d\n",root); 41 // dfs(root); 42 // } 43 //以上用于debug*/ 44 void newnode(int &x,int v,int fa)//新建一结点 45 { 46 x = ++tot; 47 ch[x][0]=ch[x][1] = 0; 48 pre[x] = fa; 49 key[x] = v; 50 po[v] = x; 51 } 52 void pushup(int w)//由儿子更新其父亲 53 { 54 } 55 void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋 56 { 57 int y = pre[r]; 58 ch[y][!kind] = ch[r][kind]; 59 pre[ch[r][kind]] = y; 60 if(pre[y]) 61 { 62 ch[pre[y]][ch[pre[y]][1]==y] = r; 63 } 64 pre[r] = pre[y]; 65 ch[r][kind] = y; 66 pre[y] = r; 67 pushup(y); 68 pushup(r); 69 } 70 void splay(int r,int goal)//将r结点旋至goal下 71 { 72 while(pre[r]!=goal) 73 { 74 if(pre[pre[r]]==goal) 75 { 76 rotate(r,ch[pre[r]][0]==r); 77 } 78 else 79 { 80 int y = pre[r]; 81 int kind = (ch[pre[y]][0]==y); 82 if(ch[y][kind]==r) 83 { 84 rotate(r,!kind); 85 rotate(r,kind); 86 } 87 else 88 { 89 rotate(y,kind); 90 rotate(r,kind); 91 } 92 } 93 } 94 pushup(r); 95 if(goal==0) root = r; 96 } 97 int get_min(int x) 98 { 99 while(ch[x][0]) 100 x = ch[x][0]; 101 return x; 102 } 103 int get_max(int x) 104 { 105 while(ch[x][1]) 106 x = ch[x][1]; 107 return x; 108 } 109 void update(int x,int y) //更新区间信息 110 { 111 int l = po[x],r = po[x+n]; 112 splay(l,0); 113 splay(r,0); 114 int ll = ch[l][0]; 115 int rr = ch[r][1]; 116 pre[ll] = pre[rr] = 0; 117 ch[r][1] = ch[l][0] = 0; 118 119 int tll = get_max(ll); 120 if(tll!=0) 121 ch[tll][1] = rr; 122 pre[rr] = tll; 123 124 if(y==0) return ; 125 if(query(y)==x) 126 { 127 ch[r][1] = rr; 128 ch[l][0] = ll; 129 pre[ll] = l; 130 pre[rr] = r; 131 ch[tll][1] = 0; 132 pre[0] = 0; 133 return ; 134 } 135 136 if(rr!=0) splay(rr,0); 137 int tt = po[y]; 138 splay(tt,0); 139 int tq = get_min(ch[tt][1]); 140 splay(tq,tt); 141 ch[tq][0] = r; 142 pre[r] = tq; 143 } 144 int query(int x)//询问l,r区间,将第l-1个结点旋自根,第r+1个结点旋自根的有儿子, 145 { 146 splay(po[x],0); 147 int k = get_min(po[x]); 148 return key[k]; 149 } 150 void build(int &x,int l,int r,int fa) 151 { 152 int m = (l+r)>>1; 153 if(l>r) return ; 154 newnode(x,dd[m],fa); 155 build(ch[x][0],l,m-1,x); 156 build(ch[x][1],m+1,r,x); 157 pushup(x); 158 } 159 void init() 160 { 161 root = tot = 0; 162 memset(ch,0,sizeof(ch)); 163 memset(pre,0,sizeof(pre)); 164 memset(key,0,sizeof(key)); 165 memset(po,0,sizeof(po)); 166 } 167 } SP; 168 void dfs(int u) 169 { 170 int i; 171 dd.push_back(u); 172 for(i = 0; i < ed[u].size(); i++) 173 { 174 int v = ed[u][i]; 175 dfs(v); 176 } 177 dd.push_back(u+n); 178 } 179 int main() 180 { 181 int i; 182 int q; 183 int mark = false; 184 while(scanf("%d",&n)!=EOF) 185 { 186 if(mark) 187 puts(""); 188 else 189 mark = true; 190 SP.init(); 191 for(i = 0; i <= n; i++) 192 { 193 ed[i].clear(); 194 } 195 dd.clear(); 196 for(i = 1; i <= n; i++) 197 { 198 int x; 199 scanf("%d",&x); 200 ed[x].push_back(i); 201 } 202 dfs(0); 203 int o = 1; 204 scanf("%d",&q); 205 stack<int>st; 206 for(i = 1 ; i < dd.size()-1 ; i++) 207 { 208 int x = dd[i]; 209 if(x<=n) st.push(x); 210 else st.pop(); 211 if(st.empty()) 212 { 213 SP.build(SP.root,o,i,0); 214 o = i+1; 215 } 216 } 217 int stt = 1; 218 while(q--) 219 { 220 char sq[100]; 221 int x,y; 222 scanf("%s",sq); 223 if(sq[0]==‘Q‘) 224 { 225 scanf("%d",&x); 226 printf("%d\n",SP.query(x)); 227 } 228 else 229 { 230 scanf("%d%d",&x,&y); 231 SP.update(x,y); 232 } 233 } 234 } 235 return 0; 236 }
hdu2475Box(splay树形转线性),布布扣,bubuko.com
时间: 2024-10-11 13:34:43