博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LCT总结
阅读量:5319 次
发布时间:2019-06-14

本文共 11739 字,大约阅读时间需要 39 分钟。

[ZJOI2008]树的统计Count

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std; 14 #define FILE "dealing" 15 #define up(i,j,n) for(int i=(j);i<=(n);i++) 16 #define pii pair
17 #define LL long long 18 namespace IO{ 19 char buf[1<<15],*fs,*ft; 20 int gc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 21 int read(){ 22 int ch=gc(),f=0,x=0; 23 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=gc();} 24 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 25 return f?-x:x; 26 } 27 int readint(){ 28 int ch=getchar(),f=0,x=0; 29 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 31 return f?-x:x; 32 } 33 }using namespace IO; 34 const int maxn=31000,inf=100000000; 35 int n,m,top=0; 36 int c[maxn][2],siz[maxn],rev[maxn]; 37 int fa[maxn],u[maxn],v[maxn],q[maxn]; 38 LL w[maxn],sum[maxn],mx[maxn]; 39 inline bool isroot(int x){ return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} 40 void updata(int x){ 41 sum[x]=sum[c[x][1]]+sum[c[x][0]]+w[x]; 42 mx[x]=max(w[x],max(mx[c[x][1]],mx[c[x][0]])); 43 } 44 void pushdown(int x){ 45 if(rev[x]){ 46 rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1; 47 swap(c[x][0],c[x][1]); 48 } 49 } 50 void rotate(int x){ 51 int y=fa[x],z=fa[y],l; 52 l=(c[y][1]==x); 53 if(!isroot(y))c[z][c[z][1]==y]=x; 54 fa[c[x][l^1]]=y;fa[y]=x;fa[x]=z; 55 c[y][l]=c[x][l^1];c[x][l^1]=y; 56 updata(y);updata(x); 57 } 58 void splay(int x){ 59 q[++top]=x; 60 for(int i=x;!isroot(i);i=fa[i]) 61 q[++top]=fa[i]; 62 while(top)pushdown(q[top--]); 63 while(!isroot(x)){ 64 int y=fa[x],z=fa[y]; 65 if(!isroot(y)){ 66 if(c[y][0]==x^c[z][0]==y)rotate(x); 67 else rotate(y); 68 } 69 rotate(x); 70 } 71 } 72 void access(int x){ 73 for(int t=0;x;t=x,x=fa[x]) 74 splay(x),c[x][1]=t,updata(x); 75 } 76 void makeroot(int x){ 77 access(x); 78 splay(x); 79 rev[x]^=1; 80 } 81 void link(int x,int y){ 82 makeroot(x); 83 fa[x]=y; 84 } 85 void split(int x,int y){ 86 makeroot(x); 87 access(y); 88 splay(y); 89 } 90 char s[10];int x,y; 91 int main(){ 92 n=readint();mx[0]=-inf; 93 up(i,1,n-1)u[i]=readint(),v[i]=readint(); 94 up(i,1,n)mx[i]=sum[i]=w[i]=readint(); 95 up(i,1,n-1)link(u[i],v[i]); 96 m=readint(); 97 while(m--){ 98 scanf("%s",s);x=readint(),y=readint(); 99 if(s[1]=='H'){100 splay(x);w[x]=y;updata(x);101 }102 else if(s[1]=='M')split(x,y),printf("%lld\n",mx[y]);103 else split(x,y),printf("%lld\n",sum[y]);104 }105 return 0;106 }
View Code

[sdoi2011] 染色

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std; 14 #define FILE "dealing" 15 #define up(i,j,n) for(int i=(j);i<=(n);i++) 16 #define pii pair
17 #define LL int 18 #define mem(f,g) memset(f,g,sizeof(f)) 19 namespace IO{ 20 char buf[1<<15],*fs,*ft; 21 int gc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 22 int read(){ 23 int ch=gc(),f=0,x=0; 24 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=gc();} 25 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 26 return f?-x:x; 27 } 28 int readint(){ 29 int ch=getchar(),f=0,x=0; 30 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=getchar();} 31 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 32 return f?-x:x; 33 } 34 }using namespace IO; 35 const int maxn=201000,inf=100000000; 36 int n,m,top; 37 int fa[maxn],sum[maxn],l[maxn],r[maxn],v[maxn],f[maxn],c[maxn][2],q[maxn],rev[maxn]; 38 void updata(int x){ 39 sum[x]=1; 40 if(c[x][0])sum[x]+=sum[c[x][0]]-(v[x]==r[c[x][0]]),l[x]=l[c[x][0]]; 41 else l[x]=v[x]; 42 if(c[x][1])sum[x]+=sum[c[x][1]]-(v[x]==l[c[x][1]]),r[x]=r[c[x][1]]; 43 else r[x]=v[x]; 44 } 45 void change(int x,int d){ 46 l[x]=r[x]=v[x]=f[x]=d; 47 sum[x]=1; 48 } 49 void w(int x){swap(l[x],r[x]);} 50 void pushdown(int x){ 51 if(rev[x]){ 52 rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1; 53 w(c[x][0]);w(c[x][1]); 54 swap(c[x][0],c[x][1]); 55 updata(x); 56 } 57 if(f[x]!=-1){ 58 if(c[x][0])change(c[x][0],f[x]); 59 if(c[x][1])change(c[x][1],f[x]); 60 f[x]=-1; 61 } 62 } 63 bool isroot(int x){ 64 return c[fa[x]][1]!=x&&c[fa[x]][0]!=x; 65 } 66 void rotate(int x){ 67 int d,y=fa[x],z=fa[y]; 68 d=(c[y][1]==x); 69 if(!isroot(y))c[z][c[z][1]==y]=x; 70 fa[x]=z;fa[y]=x;fa[c[x][d^1]]=y; 71 c[y][d]=c[x][d^1];c[x][d^1]=y; 72 updata(y);updata(x); 73 } 74 void splay(int x){ 75 q[++top]=x; 76 for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; 77 while(top)pushdown(q[top--]); 78 while(!isroot(x)){ 79 int y=fa[x],z=fa[y]; 80 if(!isroot(y)){ 81 if((c[y][1]==x)^(c[z][1]==y))rotate(y); 82 else rotate(x); 83 } 84 rotate(x); 85 } 86 } 87 void access(int x){ 88 for(int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x); 89 } 90 void makeroot(int x){ 91 access(x);splay(x);rev[x]^=1;swap(l[x],r[x]); 92 } 93 void link(int x,int y){ 94 makeroot(x);fa[x]=y;splay(x); 95 } 96 int x,y,z; 97 char s; 98 int main(){ 99 //freopen(FILE".in","r",stdin);100 //freopen(FILE".out","w",stdout);101 n=readint(),m=readint();102 mem(f,-1);mem(l,-1);mem(r,-1);mem(v,-1);103 up(i,1,n)l[i]=v[i]=r[i]=readint();104 up(i,1,n-1){105 x=readint(),y=readint();106 link(x,y);107 }108 while(m--){109 scanf(" %c",&s);x=readint(),y=readint();110 if(s=='Q'){111 makeroot(x);112 access(y);113 splay(y);114 printf("%d\n",sum[y]);115 }116 else {117 makeroot(x);118 access(y);119 splay(y);120 z=readint();121 change(y,z);122 splay(x);123 }124 }125 return 0;126 }
View Code

[SDOI2008]洞穴勘测

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std; 14 #define FILE "dealing" 15 #define up(i,j,n) for(int i=(j);i<=(n);i++) 16 #define pii pair
17 #define LL long long 18 namespace IO{ 19 char buf[1<<15],*fs,*ft; 20 int gc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 21 int read(){ 22 int ch=gc(),f=0,x=0; 23 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=gc();} 24 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 25 return f?-x:x; 26 } 27 int readint(){ 28 int ch=getchar(),f=0,x=0; 29 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 31 return f?-x:x; 32 } 33 }using namespace IO; 34 const int maxn=101000,inf=100000000; 35 int n,m,top=0; 36 int c[maxn][2],siz[maxn],rev[maxn]; 37 int fa[maxn],u[maxn],v[maxn],q[maxn]; 38 LL w[maxn],sum[maxn],mx[maxn]; 39 inline bool isroot(int x){ return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} 40 void pushdown(int x){ 41 if(rev[x]){ 42 rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1; 43 swap(c[x][0],c[x][1]); 44 } 45 } 46 void rotate(int x){ 47 int y=fa[x],z=fa[y],l; 48 l=(c[y][1]==x); 49 if(!isroot(y))c[z][c[z][1]==y]=x; 50 fa[c[x][l^1]]=y;fa[y]=x;fa[x]=z; 51 c[y][l]=c[x][l^1];c[x][l^1]=y; 52 } 53 void splay(int x){ 54 q[++top]=x; 55 for(int i=x;!isroot(i);i=fa[i]) 56 q[++top]=fa[i]; 57 while(top)pushdown(q[top--]); 58 while(!isroot(x)){ 59 int y=fa[x],z=fa[y]; 60 if(!isroot(y)){ 61 if(c[y][0]==x^c[z][0]==y)rotate(x); 62 else rotate(y); 63 } 64 rotate(x); 65 } 66 } 67 void access(int x){ 68 for(int t=0;x;t=x,x=fa[x]) 69 splay(x),c[x][1]=t; 70 } 71 void makeroot(int x){ 72 access(x); 73 splay(x); 74 rev[x]^=1; 75 } 76 void link(int x,int y){ 77 makeroot(x); 78 fa[x]=y; 79 splay(x); 80 } 81 void split(int x,int y){ 82 makeroot(x); 83 access(y); 84 splay(y); 85 } 86 int getl(int x){ 87 while(c[x][0])x=c[x][0]; 88 return x; 89 } 90 char s[10];int x,y; 91 int main(){ 92 //freopen(FILE".in","r",stdin); 93 //freopen(FILE".out","w",stdout); 94 n=readint();m=readint(); 95 while(m--){ 96 scanf("%s",s);x=readint(),y=readint(); 97 if(s[0]=='Q'){ 98 makeroot(x); 99 access(y);100 splay(y);101 if(getl(y)==x)printf("Yes\n");102 else printf("No\n");103 }104 if(s[0]=='D'){105 split(x,y);106 c[y][0]=fa[x]=0;107 }108 if(s[0]=='C'){109 link(x,y);110 }111 112 }113 return 0;114 }
View Code

[hnoi2010]弹飞绵羊

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std;14 #define FILE "dealing"15 #define up(i,j,n) for(int i=(j);i<=(n);i++)16 #define pii pair
17 #define LL int18 #define mem(f,g) memset(f,g,sizeof(f))19 namespace IO{20 char buf[1<<15],*fs,*ft;21 int gc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;}22 int read(){23 int ch=gc(),f=0,x=0;24 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=gc();}25 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}26 return f?-x:x;27 }28 int readint(){29 int ch=getchar(),f=0,x=0;30 while(ch<'0'||ch>'9'){ if(ch=='-')f=1;ch=getchar();}31 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}32 return f?-x:x;33 }34 }using namespace IO;35 const int maxn=201000,inf=100000000;36 int n,m,top;37 int fa[maxn],f[maxn],c[maxn][2],q[maxn],rev[maxn],siz[maxn],v[maxn];38 void updata(int x){39 siz[x]=1+siz[c[x][0]]+siz[c[x][1]];40 }41 bool isroot(int x){42 return c[fa[x]][1]!=x&&c[fa[x]][0]!=x;43 }44 void rotate(int x){45 int d,y=fa[x],z=fa[y];46 d=(c[y][1]==x);47 if(!isroot(y))c[z][c[z][1]==y]=x;48 fa[x]=z;fa[y]=x;fa[c[x][d^1]]=y;49 c[y][d]=c[x][d^1];c[x][d^1]=y;50 updata(y);updata(x);51 }52 void splay(int x){53 while(!isroot(x)){54 int y=fa[x],z=fa[y];55 if(!isroot(y)){56 if((c[y][1]==x)^(c[z][1]==y))rotate(y);57 else rotate(x);58 }59 rotate(x);60 }61 }62 void access(int x){63 for(int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x);64 }65 void cut(int x,int y){66 access(x);splay(y);c[y][1]=fa[x]=0;updata(y);67 }68 int x,y,z;69 char s;70 int main(){71 //freopen(FILE".in","r",stdin);72 //freopen(FILE".out","w",stdout);73 n=read();74 up(i,1,n)v[i]=read();75 for(int i=n;i>=1;i--)if(v[i]+i<=n)fa[i]=v[i]+i;76 m=read();77 while(m--){78 z=read();x=read()+1;79 if(z==1){80 access(x);81 splay(x);82 printf("%d\n",siz[x]);83 }84 else{85 y=read();86 cut(x,v[x]+x);87 if(y+x<=n)fa[x]=y+x;88 else fa[x]=0;89 v[x]=y;90 }91 }92 return 0;93 }
View Code

上面是这两天写的四道题代码;

敲了几天的LCT代码,感觉不错,决定写个总结;

 

LCT可以动态维护某点到根的某些数据;

方法:将树剖成一条条链,每条链用一个splay维护,这样查询的时候,顺着链向上以深度为关键字合并splay,这样在最后的splay上就可以查询某些信息;

首先需要构造一棵splay:

void updata(int x){	//需要维护的信息}void pushdown(int x){	//需要下传的标记}bool isroot(int x){	return c[fa[x]][1]!=x&&c[fa[x]][0]!=x;}void rotate(int x){	int d,y=fa[x],z=fa[y];	d=(c[y][1]==x);	if(!isroot(y))c[z][c[z][1]==y]=x;	fa[x]=z;fa[y]=x;fa[c[x][d^1]]=y;	c[y][d]=c[x][d^1];c[x][d^1]=y;	updata(y);updata(x);}void splay(int x){	q[++top]=x;	for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];	while(top)pushdown(q[top--]);	while(!isroot(x)){		int y=fa[x],z=fa[y];		if(!isroot(y)){			if((c[y][1]==x)^(c[z][1]==y))rotate(y);			else rotate(x);		}		rotate(x);	}}

操作1:access(LCT的核心操作):

void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x);}

操作2:makeroot(使某个点成为所在树的根,实际是splay翻转):

void makeroot(int x){access(x);splay(x);rev[x]^=1;}

 需要注意的是,有些题目中需要维护的信息与左右子树的位置有关,打rev标机的时候注意;

 这个操作比较方便,但可以不使用;

操作3:link(连接两棵树):

void link(int x,int y){makeroot(x);fa[x]=y;splay(x);}

 也有其他写法;

操作4:cut(断开两个树):

void cut(int x,int y){makeroot(x);access(y);splay(x);c[x][1]=fa[y]=0;}

时间上: 

LCT的常数大(主要是splay),但很灵活,很多无良出题人喜欢卡LCT;

树链剖分不能动态维护信息;

 

转载于:https://www.cnblogs.com/chadinblog/p/6140862.html

你可能感兴趣的文章
AndroidArchitecture
查看>>
原生JavaScript第六篇
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
大数据学习
查看>>
简单工厂模式
查看>>
Delphi7编译的程序自动中Win32.Induc.a病毒的解决办法
查看>>
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>
Centos7.2正常启动关闭CDH5.16.1
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>
Java 实践:生产者与消费者
查看>>
[转]IOCP--Socket IO模型终结篇
查看>>
(五)归一化
查看>>
使用信号量
查看>>