lct总结

Posted iboom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lct总结相关的知识,希望对你有一定的参考价值。

  时间问题 lct先到这里吧

lct就是splay维护实链剖分

易错点

几个需要pushup的地方

1.rotate pushup(y);

2.splay pushup(x);

3.access pushup(x);

4.cut 最后

pushdown

1.find pushdown(x);

2.splay 堆栈pushdown

修改时 转到splay根(不需要翻转) 再修改 维护pushup准确性

同样 pushdown时转到上面的根(翻转)

 

作用

1.维护一个可以分列合并的集合

例题1:sdoi2008洞穴探险

维护link cut find操作

代码很短 因为不用pushup

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 100005
 4 struct node{int ch[2],fa,tag;}t[maxn];
 5 int s[maxn],v[maxn],st[maxn];
 6 bool nroot(int x){return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;}
 7 void rotate(int x){
 8     int k=t[t[x].fa].ch[1]==x,y=t[x].fa,z=t[y].fa,w=t[x].ch[!k];
 9     if(nroot(y))if(t[z].ch[1]==y)t[z].ch[1]=x;else t[z].ch[0]=x;
10     t[x].ch[!k]=y,t[y].ch[k]=w,t[x].fa=z,t[y].fa=x;if(w)t[w].fa=y;
11 }
12 void pushtag(int x){swap(t[x].ch[1],t[x].ch[0]),t[x].tag^=1;}
13 void pushdown(int x){if(t[x].tag){if(t[x].ch[1])pushtag(t[x].ch[1]);if(t[x].ch[0])pushtag(t[x].ch[0]);t[x].tag=0;}
14 }
15 void splay(int x){int y=x,z=0;st[++z]=y;
16     while(nroot(y))st[++z]=y=t[y].fa;
17     while(z)pushdown(st[z--]);
18     while(nroot(x)){y=t[x].fa;z=t[y].fa;
19         if(nroot(y))rotate((t[y].ch[0]==x)^(t[z].ch[0]==y)?x:y);
20         rotate(x);
21     }
22 }
23 void access(int x){for(int y=0;x;y=x,x=t[x].fa)splay(x),t[x].ch[1]=y;}
24 int find(int rt){access(rt);splay(rt);while(t[rt].ch[0])pushdown(rt),rt=t[rt].ch[0];return rt;}
25 void makeroot(int x){access(x),splay(x),pushtag(x);}
26 void link(int x,int y){makeroot(x);t[x].fa=y;}
27 void split(int x,int y){makeroot(x);access(y);splay(y);}
28 void cut(int x,int y){split(x,y);t[y].ch[0]=0,t[x].fa=0;} 
29 int main(){int n,m;cin>>n>>m;
30     while(m--){char ch[1000];int x,y;cin>>ch>>x>>y;
31         if(ch[0]==Q){if(find(x)==find(y))cout<<"Yes"<<endl;else cout<<"No"<<endl;}
32         else if(ch[0]==C)link(x,y);
33         else if(ch[0]==D)cut(x,y);
34     }return 0;
35 }
View Code

 

3141161 zhengzhi726 2049 Accepted 4028 kb 6256 ms C++/Edit 1593 B 2019-02-06 10:41:43

2.部落冲突

一样一样的

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 300005
 4 struct node{
 5     int ch[2],fa,tag;
 6 }t[maxn];
 7 int s[maxn],v[maxn],st[maxn],u[maxn];
 8 bool nroot(int x){
 9     return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;
10 }
11 void rotate(int x){
12     int k=t[t[x].fa].ch[1]==x,y=t[x].fa,z=t[y].fa,w=t[x].ch[!k];
13     if(nroot(y))if(t[z].ch[1]==y)t[z].ch[1]=x;else t[z].ch[0]=x;
14     t[x].ch[!k]=y,t[y].ch[k]=w,t[x].fa=z,t[y].fa=x;if(w)t[w].fa=y;
15 }
16 void pushtag(int x){
17     swap(t[x].ch[1],t[x].ch[0]),t[x].tag^=1;
18 }
19 void pushdown(int x){
20     if(t[x].tag){
21         if(t[x].ch[1])pushtag(t[x].ch[1]);
22         if(t[x].ch[0])pushtag(t[x].ch[0]);
23         t[x].tag=0;
24     }
25 }
26 void splay(int x){
27     int y=x,z=0;
28     st[++z]=y;
29     while(nroot(y))st[++z]=y=t[y].fa;
30     while(z)pushdown(st[z--]);
31     while(nroot(x)){
32         y=t[x].fa;z=t[y].fa;
33         if(nroot(y))
34             rotate((t[y].ch[0]==x)^(t[z].ch[0]==y)?x:y);
35         rotate(x);
36     }
37 }
38 void access(int x){
39     for(int y=0;x;y=x,x=t[x].fa)splay(x),t[x].ch[1]=y;
40 }
41 int find(int rt){
42     access(rt);splay(rt);
43     while(t[rt].ch[0])rt=t[rt].ch[0];
44     return rt;
45 }
46 void makeroot(int x){
47     access(x),splay(x),pushtag(x);
48 }
49 void link(int x,int y){
50     makeroot(x);t[x].fa=y;
51 }
52 void split(int x,int y){
53     makeroot(x);
54     access(y);splay(y);
55 }
56 void cut(int x,int y){
57     split(x,y);if(t[y].ch[0]==x)t[y].ch[0]=0,t[x].fa=0;
58 }
59 int main(){
60     register char ch;
61     int n,m,p=0,a,b;cin>>n>>m;
62     for(int i=1;i<n;++i){cin>>a>>b;link(a,b);}
63     while(m--){cin>>ch;
64         switch(ch){
65         case U:cin>>a;link(u[a],v[a]);break;
66         case C:cin>>a>>b;++p;cut(u[p]=a,v[p]=b);break;
67         case Q:cin>>a>>b;puts(find(a)==find(b)?"Yes":"No");
68         }
69     }
70     return 0;
71 }
View Code
 2114ms /  5.68MB 
代码:1.76KB C++

3.模板 有难度 一直不太对 就重写了 然后就过了

注意细节

技术图片
 1 // luogu-judger-enable-o2
 2 // luogu-judger-enable-o2
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 #define maxn 100005
 6 struct node{
 7     int ch[2],fa,tag;
 8 }t[maxn];
 9 int s[maxn],v[maxn],st[maxn];
10 bool nroot(int x){
11     return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;
12 }
13 void pushup(int x){
14     s[x]=s[t[x].ch[0]]^s[t[x].ch[1]]^v[x];
15 }
16 void pushtag(int x){
17     swap(t[x].ch[1],t[x].ch[0]),t[x].tag^=1;
18 }
19 void rotate(int x){
20     int k=t[t[x].fa].ch[1]==x,y=t[x].fa,z=t[y].fa,w=t[x].ch[!k];
21     if(nroot(y))if(t[z].ch[1]==y)t[z].ch[1]=x;else t[z].ch[0]=x;
22     t[x].ch[!k]=y,t[y].ch[k]=w,t[x].fa=z,t[y].fa=x;if(w)t[w].fa=y;
23     pushup(y);
24 }
25 void pushdown(int x){
26     if(t[x].tag){
27         if(t[x].ch[1])pushtag(t[x].ch[1]);
28         if(t[x].ch[0])pushtag(t[x].ch[0]);
29         t[x].tag=0;
30     }
31 }
32 void splay(int x){
33     int y=x,z=0;
34     st[++z]=y;
35     while(nroot(y))st[++z]=y=t[y].fa;
36     while(z)pushdown(st[z--]);
37     while(nroot(x)){
38         y=t[x].fa;z=t[y].fa;
39         if(nroot(y))
40             rotate((t[y].ch[0]==x)^(t[z].ch[0]==y)?x:y);
41         rotate(x);
42     } pushup(x);
43 }
44 void access(int x){
45     for(int y=0;x;y=x,x=t[x].fa)splay(x),t[x].ch[1]=y,pushup(x);
46 }
47 int find(int x){
48     access(x),splay(x);
49     while(t[x].ch[0])pushdown(x)/*!!!!!*/,x=t[x].ch[0];splay(x);
50     return x;
51 }
52 void makeroot(int x){
53     access(x),splay(x),pushtag(x);
54 }
55 void link(int x,int y){
56     makeroot(x);
57     if(find(y)!=x)t[x].fa=y;
58 }
59 void cut(int x,int y){
60     makeroot(x);
61     if(find(y)==x&&t[y].fa==x&&!t[y].ch[0]){
62         t[y].fa=t[x].ch[1]=0;
63         pushup(x);
64     }
65 }
66 void split(int x,int y){
67     makeroot(x);
68     access(y);splay(y);
69 }
70 int main()
71 {
72     int n,m;cin>>n>>m;
73     for(int i=1;i<=n;++i)cin>>v[i];
74     while(m--){
75         int type,x,y;cin>>type>>x>>y;
76         switch(type){
77         case 0:split(x,y);printf("%d
",s[y]);break;
78         case 1:link(x,y);break;
79         case 2:cut(x,y);break;
80         case 3:splay(x);v[x]=y;
81         }
82     }
83     return 0;
84 }
View Code
 1837ms /  2.94MB 
代码:1.98KB C++

4.Tree II

 8892ms /  8.39MB 
代码:2.45KB C++
技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 100005
 4 #define mod 51061
 5 #define lc t[x].ch[0]
 6 #define rc t[x].ch[1]
 7 #define mul(x) x*=c;x%=mod
 8 #define add(x,c) x+=c;x%=mod
 9 #define ll long long
10 struct node{
11     ll ch[2],fa,tag;
12 }t[maxn];
13 ll s[maxn],v[maxn],lm[maxn],la[maxn],sz[maxn],st[maxn],n,q,a,b,k;
14 char cc;
15 bool nroot(int x){
16     return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;
17 }
18 void pushtag(int x){
19     swap(t[x].ch[1],t[x].ch[0]),t[x].tag^=1;
20 }
21 void pushup(int x){
22     s[x]=(s[lc]+s[rc]+v[x])%mod;
23     sz[x]=sz[lc]+sz[rc]+1;
24 }
25 void pushm(int x,int c){//
26     mul(s[x]);mul(v[x]);mul(lm[x]);mul(la[x]);
27 }
28 void pusha(int x,int c){//
29     add(s[x],c*sz[x]);add(v[x],c);add(la[x],c);
30 }
31 void pushdown(int x){
32     if(lm[x]!=1)pushm(lc,lm[x]),pushm(rc,lm[x]),lm[x]=1;
33     if(la[x])   pusha(lc,la[x]),pusha(rc,la[x]),la[x]=0;
34     if(t[x].tag)   {if(lc)pushtag(lc);if(rc)pushtag(rc);t[x].tag=0;}
35 }
36 void rotate(int x){
37     int k=t[t[x].fa].ch[1]==x,y=t[x].fa,z=t[y].fa,w=t[x].ch[!k];
38     if(nroot(y)){if(t[z].ch[1]==y)t[z].ch[1]=x;else t[z].ch[0]=x;} 
39     t[x].ch[!k]=y,t[y].ch[k]=w,t[x].fa=z,t[y].fa=x;if(w)t[w].fa=y;
40     pushup(y);
41 }
42 void splay(int x){
43     int y=x,z=0;
44     st[++z]=y;
45     while(nroot(y))st[++z]=y=t[y].fa;
46     while(z)pushdown(st[z--]);
47     while(nroot(x)){
48         y=t[x].fa;z=t[y].fa;
49         if(nroot(y))
50             rotate((t[y].ch[0]==x)^(t[z].ch[0]==y)?x:y);
51         rotate(x);
52     } pushup(x);
53 }
54 void access(int x){
55     for(int y=0;x;y=x,x=t[x].fa)splay(x),t[x].ch[1]=y,pushup(x);
56 }
57 int find(int x){
58     access(x),splay(x);
59     while(t[x].ch[0])pushdown(x)/*!!!!!*/,x=t[x].ch[0];splay(x);
60     return x;
61 }
62 void makeroot(int x){
63     access(x),splay(x),pushtag(x);
64 }
65 void link(int x,int y){
66     makeroot(x);
67     if(find(y)!=x)t[x].fa=y;
68 }
69 void cut(int x,int y){
70     makeroot(x);
71     if(find(y)==x&&t[y].fa==x&&!t[y].ch[0]){
72         t[y].fa=t[x].ch[1]=0;
73         pushup(x);
74     }
75 }
76 void split(int x,int y){
77     makeroot(x);
78     access(y);splay(y);
79 }
80 int main(){cin>>n>>q;
81     for(int i=1;i<=n;i++)v[i]=sz[i]=lm[i]=1;
82     for(int i=1;i<n;i++)cin>>a>>b,link(a,b);
83     for(int i=1;i<=q;i++){cin>>cc;
84         if(cc==+){cin>>a>>b>>k;split(a,b);pusha(b,k);}
85         else if(cc==-){cin>>a>>b;cut(a,b);cin>>a>>b;link(a,b);}
86         else if(cc==*){cin>>a>>b>>k;split(a,b);pushm(b,k);}
87         else if(cc==/){cin>>a>>b;split(a,b);printf("%d
",s[b]);}
88     }return 0;
89 }
View Code

5魔法森林

lct 除了点度和树结构 啥都不一定

所以需要边上挂点 而不是权值归到下一个点(qtree 那样——一个树剖题)

代码高度借鉴flashhu大佬 就不贴了
 
 1639ms /  6.89MB 
代码:2.11KB C++
3141171 zhengzhi726 3669 Accepted 7284 kb 4052 ms C++/Edit 2371 B 2019-02-06 10:52:14








以上是关于lct总结的主要内容,如果未能解决你的问题,请参考以下文章

LCT总结——应用篇(附题单)(LCT)

LCT入门总结

lct总结

lct总结

LCT好题总结

洛谷P4219 [BJOI2014]大融合(LCT,Splay)