hdu2475Box(splay树形转线性)

链接

推荐一篇帖子

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
",
 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
",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
",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 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3801761.html