首页 > 代码库 > hdu5967

hdu5967

看到合肥赛区的题目都是泪啊,期末考完了来补几道

公正来说,这道题我考场确实写不出来,因为我的lct模板不够完美……

我在学习lct的时候不知道为什么代码里加边、删边都是用了一个makeroot的操作

这样我的lct就只能维护无根树而不能维护有根树

但事实上,lct是完全可以维护像这道题有向基环外向树一类有根树

那么怎么加边删边呢?

加边x和x的父亲y:只要先access(x) 再把x所属的Auxiliary Tree的Path parent更改y即可(即splay(x),fa[x]=y)

删除x和x的父亲y:先access(x),splay(x),这时断开Auxiliary Tree上根与左子树的连接即可

当然如果涉及到换根的操作,那还是要用makeroot的,这样lct就能维护有根树了

这道题,我们就是维护森林,成环的边不加(根如果有后继先不加),当遇到修改后继的时候再考虑根的后继是否可以加入,查询即找根是否有后继即可

技术分享
  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 int son[200010][2],a[200010],fa[200010];
  5 int n,m,pre;
  6 bool rev[200010],can[200010];
  7 bool root(int x)
  8 {
  9     return (son[fa[x]][0]!=x&&son[fa
 10 
 11 [x]][1]!=x);
 12 }
 13 
 14 void rot(int x,int w)
 15 {
 16     int y=fa[x];
 17     if (!root(y))
 18     {
 19         if (son[fa[y]][0]==y) son[fa
 20 
 21 [y]][0]=x;
 22         else son[fa[y]][1]=x;
 23     }
 24     fa[x]=fa[y];
 25     son[y][w^1]=son[x][w];
 26     if (son[x][w]) fa[son[x][w]]=y;
 27     son[x][w]=y; fa[y]=x;
 28 }
 29 
 30 void splay(int x)
 31 {
 32     while (!root(x))
 33     {
 34         int y=fa[x];
 35         if (root(y))
 36         {
 37             if (son[y][0]==x) rot(x,1); 
 38 
 39 else rot(x,0);
 40         }
 41         else {
 42             if (son[fa[y]][0]==y)
 43             {
 44                 if (son[y][0]==x) rot
 45 
 46 (y,1); else rot(x,0);
 47                 rot(x,1);
 48             }
 49             else {
 50                 if (son[y][1]==x) rot
 51 
 52 (y,0); else rot(x,1);
 53                 rot(x,0);
 54             }
 55         }
 56     }
 57 }
 58 
 59 void access(int x)
 60 {
 61     int y=0;
 62     while (x)
 63     {
 64         splay(x);
 65         son[x][1]=y;
 66         y=x; x=fa[x];
 67     }
 68 }
 69 
 70 int ask(int x)
 71 {
 72     access(x);
 73     splay(x);
 74     while (son[x][0]) x=son[x][0];
 75     return x;
 76 }
 77 
 78 void link(int x,int y)
 79 {
 80     access(x);
 81     splay(x);
 82     fa[x]=y;
 83 }
 84 
 85 void cut(int x)
 86 {
 87     access(x);
 88     splay(x);
 89     int y=son[x][0];
 90     if (!y) return;
 91     fa[y]=son[x][0]=0;
 92 }
 93 
 94 void change(int x,int y)
 95 {
 96     if (y==a[x]) return;
 97     int rt=ask(x);
 98     if (can[x]) cut(x);
 99     if (x!=rt&&a[rt]&&ask(a[rt])!=ask
100 
101 (rt))
102     {
103         link(rt,a[rt]);
104         can[rt]=1;
105     }
106     if (!y) can[x]=0;
107     else {
108         if (ask(x)!=ask(y))
109         {
110             link(x,y);
111             can[x]=1;
112         }
113         else can[x]=0;
114     }
115     a[x]=y;
116 }
117 
118 int main()
119 {
120     scanf("%d%d",&n,&m);
121     for (int i=1; i<=n; i++)
122     {
123         scanf("%d",&a[i]);
124         can[i]=0;
125         if (a[i])
126         {
127             if (ask(a[i])!=ask(i))
128             {
129                 fa[i]=a[i];
130                 can[i]=1;
131             }
132             else can[i]=0;
133         }
134     }
135     int ch,x,y;
136     for (int i=1; i<=m; i++)
137     {
138         scanf("%d",&ch);
139         if (ch==1)
140         {
141             scanf("%d%d",&x,&y);
142             change(x,y);
143         }
144         else {
145             scanf("%d",&x);
146             y=ask(x);
147             printf("%d\n",a[y]?-1:y);
148         }
149     }
150 }
View Code

 

hdu5967