【BZOJ2049,2631,3282,1180】LCT模板四连A

好吧我并不想讲LCT

只是贴4个代码~

【BZOJ2049】[Sdoi2008]Cave 洞穴勘测

#include <cstdio>
#include <cstring>
#include <iostream>
#define isr(A)	(s[s[A].fa].ch[0]!=A&&s[s[A].fa].ch[1]!=A)
using namespace std;
const int maxn=10010;
int n,m;
struct NODE
{
	int ch[2],fa,rev;

}s[10010];
char str[20];
void pushdown(int x)
{
	if(s[x].rev)
	{
		swap(s[x].ch[0],s[x].ch[1]);
		if(s[x].ch[0])	s[s[x].ch[0]].rev^=1;
		if(s[x].ch[1])	s[s[x].ch[1]].rev^=1;
		s[x].rev=0;
	}
}
void rotate(int x)
{
	int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
	if(!isr(y))	s[z].ch[y==s[z].ch[1]]=x;
	s[y].ch[d]=s[x].ch[d^1],s[y].fa=x,s[x].fa=z;
	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;
	s[x].ch[d^1]=y;
}
void pd(int x){if(!isr(x))	pd(s[x].fa);	pushdown(x);}
void splay(int x)
{
	pd(x);
	while(!isr(x))
	{
		int y=s[x].fa,z=s[y].fa;
		if(!isr(y))
		{
			if((x==s[y].ch[1])^(y==s[z].ch[1]))	rotate(x);
			else	rotate(y);
		}
		rotate(x);
	}
}
void access(int x)
{
	int y=0;
	while(x)	splay(x),s[x].ch[1]=y,y=x,x=s[x].fa;
}
void maker(int x)
{
	access(x),splay(x),s[x].rev^=1;
}
int findr(int x)
{
	access(x),splay(x);
	while(s[x].ch[0])	pushdown(x),x=s[x].ch[0];
	return x;
}
void link(int x,int y)
{
	maker(x),s[x].fa=y;
}
void cut(int x,int y)
{
	maker(y),access(x),splay(x);
	s[x].ch[0]=s[y].fa=0;
}
int rd()
{
	int ret=0;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	gc=getchar();
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret;
}
int main()
{
	n=rd(),m=rd();
	int i,a,b;
	for(i=1;i<=m;i++)
	{
		scanf("%s",str);
		a=rd(),b=rd();
		switch(str[0])
		{
			case ‘D‘:cut(a,b);	break;
			case ‘C‘:link(a,b);	break;
			case ‘Q‘:if(findr(a)==findr(b))	printf("Yes\n");
			else	printf("No\n");
		}
	}
	return 0;
}

【BZOJ2631】tree

此题的下传标记实在是长,好在我把它写到结构体里了

据说此题必须用unsigned int,不明觉厉~

#include <cstdio>
#include <cstring>
#include <iostream>
#define isr(A)	(s[s[A].fa].ch[0]!=A&&s[s[A].fa].ch[1]!=A)
#define mod 51061
using namespace std;
typedef unsigned int ui;
struct node
{
	ui ch[2],fa,rev;
	ui ts,tc,sum,siz,v;
	void C(ui x)	{v=v*x%mod,sum=sum*x%mod,tc=tc*x%mod,ts=ts*x%mod;}
	void S(ui x)	{v=(v+x)%mod,sum=(sum+siz*x)%mod,ts=(ts+x)%mod;}
}s[100010];
char str[10];
ui n,m;
void pushup(ui x)
{
	s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
	s[x].sum=(s[s[x].ch[0]].sum+s[s[x].ch[1]].sum+s[x].v)%mod;
}
void pushdown(ui x)
{
	if(s[x].rev)
	{
		swap(s[x].ch[0],s[x].ch[1]);
		if(s[x].ch[0])	s[s[x].ch[0]].rev^=1;
		if(s[x].ch[1])	s[s[x].ch[1]].rev^=1;
		s[x].rev=0;
	}
	if(s[x].tc!=1)
	{
		if(s[x].ch[0])	s[s[x].ch[0]].C(s[x].tc);
		if(s[x].ch[1])	s[s[x].ch[1]].C(s[x].tc);
		s[x].tc=1;
	}
	if(s[x].ts)
	{
		if(s[x].ch[0])	s[s[x].ch[0]].S(s[x].ts);
		if(s[x].ch[1])	s[s[x].ch[1]].S(s[x].ts);
		s[x].ts=0;
	}
}
void rotate(ui x)
{
	ui y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
	if(!isr(y))	s[z].ch[y==s[z].ch[1]]=x;
	s[y].ch[d]=s[x].ch[d^1],s[x].fa=z,s[y].fa=x;
	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;
	s[x].ch[d^1]=y;
	pushup(y),pushup(x);
}
void updata(ui x)
{
	if(!isr(x))	updata(s[x].fa);
	pushdown(x);
}
void splay(ui x)
{
	updata(x);
	while(!isr(x))
	{
		ui y=s[x].fa,z=s[y].fa;
		if(!isr(y))
		{
			if((x==s[y].ch[0])^(y==s[z].ch[0]))	rotate(x);
			else	rotate(y);
		}
		rotate(x);
	}
}
void access(ui x)
{
	ui y=0;
	while(x)	splay(x),s[x].ch[1]=y,pushup(x),y=x,x=s[x].fa;
}
void maker(ui x)
{
	access(x),splay(x),s[x].rev^=1;
}
void cut(ui x,ui y)
{
	maker(y),access(x),splay(x);
	s[x].ch[0]=s[y].fa=0,pushup(x);
}
void link(ui x,ui y)
{
	maker(y),s[y].fa=x;
}
ui rd()
{
	ui ret=0;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	gc=getchar();
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret;
}
int main()
{
	n=rd(),m=rd();
	ui i,a,b,c,d;
	for(i=1;i<=n;i++)	s[i].v=1;
	for(i=1;i<n;i++)	link(rd(),rd());
	for(i=1;i<=m;i++)
	{
		scanf("%s",str),a=rd(),b=rd();
		switch(str[0])
		{
			case ‘*‘:c=rd(),maker(a),access(b),splay(b),s[b].C(c);	break;
			case ‘+‘:c=rd(),maker(a),access(b),splay(b),s[b].S(c);	break;
			case ‘-‘:c=rd(),d=rd(),cut(a,b),link(c,d);	break;
			case ‘/‘:maker(a),access(b),splay(b),printf("%u\n",s[b].sum);	break;
		}
	}
	return 0;
}

【BZOJ3282】Tree

判断一下是否联通就好了

#include <cstdio>
#include <iostream>
#include <cstring>
#define isr(A)	(s[s[A].fa].ch[0]!=A&&s[s[A].fa].ch[1]!=A)
using namespace std;
int n,m;
struct node
{
	int ch[2],fa,sum,v,rev;
}s[300010];
void pushup(int x)
{
	s[x].sum=s[s[x].ch[0]].sum^s[s[x].ch[1]].sum^s[x].v;
}
void pushdown(int x)
{
	if(s[x].rev)
	{
		swap(s[x].ch[0],s[x].ch[1]);
		if(s[x].ch[0])	s[s[x].ch[0]].rev^=1;
		if(s[x].ch[1])	s[s[x].ch[1]].rev^=1;
		s[x].rev=0;
	}
}
void rotate(int x)
{
	int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
	if(!isr(y))	s[z].ch[y==s[z].ch[1]]=x;
	s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];
	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;
	s[x].ch[d^1]=y;
	pushup(y),pushup(x);
}
void updata(int x)
{
	if(!isr(x))	updata(s[x].fa);
	pushdown(x);
}
void splay(int x)
{
	updata(x);
	while(!isr(x))
	{
		int y=s[x].fa,z=s[y].fa;
		if(!isr(y))
		{
			if((x==s[y].ch[0])^(y==s[z].ch[0]))	rotate(x);
			else	rotate(y);
		}
		rotate(x);
	}
}
void access(int x)
{
	int y=0;
	while(x)	splay(x),s[x].ch[1]=y,pushup(x),y=x,x=s[x].fa;
}
void maker(int x)
{
	access(x),splay(x),s[x].rev^=1;
}
void cut(int x,int y)
{
	maker(x),access(y),splay(y);
	if(s[x].fa==y)	s[x].fa=s[y].ch[0]=0,pushup(y);
}
void link(int x,int y)
{
	maker(x),s[x].fa=y;
}
void split(int a,int b)
{
	maker(a),access(b),splay(b);
}
int findr(int x)
{
	access(x),splay(x);
	while(s[x].ch[0])	x=s[x].ch[0];
	return x;
}
int rd()
{
	int ret=0;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	gc=getchar();
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret;
}
int main()
{
	n=rd(),m=rd();
	int i,a,b,c;
	for(i=1;i<=n;i++)	s[i].sum=s[i].v=rd();
	for(i=1;i<=m;i++)
	{
		c=rd(),a=rd(),b=rd();
		switch(c)
		{
			case 0:split(a,b),printf("%d\n",s[b].sum);	break;
			case 1:if(findr(a)!=findr(b))	link(a,b);	break;
			case 2:cut(a,b);	break;
			case 3:splay(a),s[a].v=b,pushup(a);	break;
		}
	}
	return 0;
}

[CROATIAN2009]OTOCI

我经常把ch[]数组开成int ch[0];不知道有谁跟我经常犯一样的错误。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#define isr(A)	(s[s[A].fa].ch[0]!=A&&s[s[A].fa].ch[1]!=A)
using namespace std;
int n,m;
struct node
{
	int ch[2],fa,sum,v,rev;
}s[30010];
char str[20];
void pushup(int x)
{
	s[x].sum=s[s[x].ch[0]].sum+s[s[x].ch[1]].sum+s[x].v;
}
void pushdown(int x)
{
	if(s[x].rev)
	{
		swap(s[x].ch[0],s[x].ch[1]);
		if(s[x].ch[0])	s[s[x].ch[0]].rev^=1;
		if(s[x].ch[1])	s[s[x].ch[1]].rev^=1;
		s[x].rev=0;
	}
}
void rotate(int x)
{
	int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
	if(!isr(y))	s[z].ch[y==s[z].ch[1]]=x;
	s[y].fa=x,s[x].fa=z,s[y].ch[d]=s[x].ch[d^1];
	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;
	s[x].ch[d^1]=y;
	pushup(y),pushup(x);
}
void updata(int x)
{
	if(!isr(x))	updata(s[x].fa);
	pushdown(x);
}
void splay(int x)
{
	updata(x);
	while(!isr(x))
	{
		int y=s[x].fa,z=s[y].fa;
		if(!isr(y))
		{
			if((x==s[y].ch[0])^(y==s[z].ch[0]))	rotate(x);
			else	rotate(y);
		}
		rotate(x);
	}
}
void access(int x)
{
	int y=0;
	while(x)	splay(x),s[x].ch[1]=y,pushup(x),y=x,x=s[x].fa;
}
void maker(int x)
{
	access(x),splay(x),s[x].rev^=1;
}
void link(int x,int y)
{
	maker(x),s[x].fa=y;
}
int findr(int x)
{
	access(x),splay(x);
	while(s[x].ch[0])	x=s[x].ch[0];
	return x;
}
void split(int x,int y)
{
	maker(y),access(x),splay(x);
}
int rd()
{
	int ret=0;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	gc=getchar();
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret;
}
int main()
{
	n=rd();
	int i,a,b,c;
	for(i=1;i<=n;i++)	s[i].sum=s[i].v=rd();
	m=rd();
	for(i=1;i<=m;i++)
	{
		scanf("%s",str),a=rd(),b=rd();
		switch(str[0])
		{
			case ‘b‘:if(findr(a)!=findr(b))	printf("yes\n"),link(a,b);
					else	printf("no\n");	break;
			case ‘p‘:splay(a),s[a].v=b,pushup(a);	break;
			case ‘e‘:if(findr(a)!=findr(b))	printf("impossible\n");
					else	split(a,b),printf("%d\n",s[a].sum);	break;
		}
	}
	return 0;
}
时间: 2024-10-22 21:34:49

【BZOJ2049,2631,3282,1180】LCT模板四连A的相关文章

Xamarin XAML语言教程构建ControlTemplate控件模板 (四)

Xamarin XAML语言教程构建ControlTemplate控件模板 (四) 2.在页面级别中构建控件模板 如果开发者要在页面级别中构建控件模板,首先必须将ResourceDictionary添加到页面中,然后在ResourceDictionary中实现模板的构建即可,其语法形式如下: <Page> <Page.Resources> <ResourceDictionary> <ControlTemplate x:Key="KeyName"

2014鞍山网络预选赛1006(LCT模板题)hdu5002

Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 41    Accepted Submission(s): 10 Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node is as

LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接. 2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在. 3:后接两个整数(x,y),代表将点x上的权值变成y. 输入输出

bzoj2049-洞穴勘测(动态树lct模板题)

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

BZOJ 3282: Tree [LCT]

3282: Tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1677  Solved: 744[Submit][Status][Discuss] Description 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接.

BZOJ2049 SDOI2008 洞穴勘测 LCT

题意:给定一棵树,维护:1.删除一条边  2.添加一条边  3.询问u和v是否连通 题解:LCT维护连通性 #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=10000+2; typedef struct NODE{ NODE *ch

【模板整合】LCT模板

原题树的统计Count LCT动态维护树信息.比链剖好写但是速度真的没太有优势- #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define LL long long #define MAXN 50010 #define MAXINT 0x7fffffff using namespace std; struct

PTA Root of AVL Tree (AVL树模板+四种旋转+指针)

关于AVL树(平衡二叉搜索树,高度为lgn)的讲解,双手呈上某大佬博客:https://www.cnblogs.com/zhuwbox/p/3636783.html 我从这题get到一个新的结构体写法(姿势): typedef struct treeNode { int val; treeNode *left; treeNode *right; int height; }node, *tree;//node 是treeNode结构体,*tree是结构体指针 我对AVL树的理解: 按照插入节点时旋

LCT模板坑点总结

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int MAXN=100005; int n,m; struct LCT { int fa[MAXN],val[MAXN],rev[MAXN],ch[MAXN][2],sum[MAXN],tot; int stk[M