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 }
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 }
2114ms / 5.68MB
代码:1.76KB C++
代码: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 }
1837ms / 2.94MB
代码:1.98KB C++
代码:1.98KB C++
4.Tree II
8892ms / 8.39MB
代码:2.45KB C++
代码: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 }
5魔法森林
lct 除了点度和树结构 啥都不一定
所以需要边上挂点 而不是权值归到下一个点(qtree 那样——一个树剖题)
代码高度借鉴flashhu大佬 就不贴了
1639ms / 6.89MB
代码:2.11KB C++
代码:2.11KB C++
3141171 | zhengzhi726 | 3669 | Accepted | 7284 kb | 4052 ms | C++/Edit | 2371 B | 2019-02-06 10:52:14 |
以上是关于lct总结的主要内容,如果未能解决你的问题,请参考以下文章