最近在机房呆的时间蛮多
所以就有时间把以前学的算法复习一下
像lct这种代码量大且不好理解的代码,
一定要及时复习
以前写的模板,多少有些缺陷
所以这次整理了一个优美的
tip
快要考试,我们的目标是:不掉人品,踏实肯干
这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=1000005;
int n,m,root,cnt;
int size[N],mx[N],pre[N],v[N],ch[N][2],q[N];
bool rev[N];
struct node{
int x,y,nxt;
};
node way[N<<1];
int st[N],tot=0;
int get(int x)
{
return ch[pre[x]][0]==x ? 0:1;
//x是爸爸哪个孩子
}
int isroot(int x)
{
return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x;
//判断该节点是不是根
}
void update(int x) //这里我维护的是子树大小
{
size[x]=1;
if (ch[x][0]) size[x]+=size[ch[x][0]];
if (ch[x][1]) size[x]+=size[ch[x][1]];
}
void push(int x) //一般是用来处理翻转操作的
{
if (x&&rev[x])
{
rev[x]^=1;
if (ch[x][0]) rev[ch[x][0]]^=1;
if (ch[x][1]) rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
}
void rotate(int x)
{
int fa=pre[x];
int grand=pre[fa];
int wh=get(x);
if (!isroot(fa)) ch[grand][ch[grand][0]==fa? 0:1]=x;
//爸爸不是根,那么一定有爷爷
ch[fa][wh]=ch[x][wh^1]; //爸爸和儿子的关系一定对应好
pre[ch[fa][wh]]=fa;
pre[x]=grand; pre[fa]=x;
ch[x][wh^1]=fa;
update(fa);
update(x);
}
void splay(int x)
{
int top=0;
q[++top]=x;
for (int i=x;!isroot(i);i=pre[i]) //把该节点到根的所有节点入队
q[++top]=pre[i]; //pre[i]
while (top) push(q[top--]); //全部push
for (int fa;!isroot(x);rotate(x))
if (!isroot(fa=pre[x]))
rotate(get(fa)==get(x)? fa:x);
}
void expose(int bh)
{
int t=0;
while (bh)
{
splay(bh);
ch[bh][1]=t; //expose后节点的右儿子就没了
update(bh); //产生了一个新儿子,所以需要update
t=bh;
bh=pre[bh];
}
}
void makeroot(int bh)
{
expose(bh);
splay(bh);
rev[bh]^=1; //把x换到根上,那么ta以上的节点深度互换
}
void link(int x,int y)
{
makeroot(x);
pre[x]=y; //x转到根上之后链接,这样牵扯到的节点较少
}
void cut(int x,int y)
{
makeroot(x);
expose(y);
splay(y);
ch[y][0]=pre[x]=0;
}
int find(int bh)
{
expose(bh);
splay(bh);
while (ch[bh][0]) bh=ch[bh][0]; //找到根节点
return bh;
}
int main()
{
//两点连通性
if (find(x)==find(y)) printf("Yes
");
//两点距离
makeroot(x);
expose(y);
splay(y);
printf("%d
",size[ch[y][0]]);
//路径上的节点权值和
makeroot(x);
expose(y);
splay(y);
printf("%d
",sum[y]);
//节点到根的距离
int ro=find(x);
makeroot(ro);
expose(x);
splay(x);
printf("%d
",size[ch[x][0]]);
//更改节点值
makeroot(x);
v[x]=z;
update(x);
}