luogu3690 模板Link Cut Tree (动态树)
Posted XYZinc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu3690 模板Link Cut Tree (动态树)相关的知识,希望对你有一定的参考价值。
题目
硫硼作者想提醒大家,WA 了 TLE 了 RE 了的,也许只是主函数写错了
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <cstring>
using namespace std;
#define pa T[x].fa
#define l T[x].ch[0]
#define r T[x].ch[1]
const int N=300005;
struct lct
{
struct node
{
int ch[2],fa,sum,rev,w;//sum记录以当前节点为根的辅助树的权值和
}T[N];
bool son(int x){return T[pa].ch[1]==x;}//判断是否为右儿子
bool isroot(int x){return T[pa].ch[0]!=x&&T[pa].ch[1]!=x;}//判断节点x是否为所处辅助树的根
//每个辅助树之间是有连接的,即儿子都认父亲,父亲只认重儿子,所以当其父亲左右儿子都不为自己时,当前节点为所处辅助树的根
void reverse(int x){T[x].rev^=1;swap(l,r);}//翻转
void update(int x){T[x].sum=T[l].sum^T[r].sum^T[x].w;}//异或
void pushdown_once(int x)//下传翻转标记
{
if(!T[x].rev) return;
if(l) reverse(l); if(r) reverse(r);
T[x].rev=0;
}
void pushdown(int x){if(!isroot(x)) pushdown(pa);pushdown_once(x);}//从上往下翻转
void lk(int x,int y,int f)
{
T[x].ch[f]=y;
T[y].fa=x;
}
void rotate(int x)
{
int y=T[x].fa,z=T[y].fa,f=son(x);
if(!isroot(y)) T[z].ch[son(y)]=x;T[x].fa=z;//如果是根,儿子认父亲,父亲不认儿子
T[y].ch[f]=T[x].ch[f^1];T[T[x].ch[f^1]].fa=y;
T[x].ch[f^1]=y;T[y].fa=x;
update(y);update(x);
}
void splay(int x)//将x转至根
{
pushdown(x);
while(!isroot(x))
{
if(!isroot(pa)) rotate(son(pa)==son(x)? pa:x);
rotate(x);
}
}
/***/
void access(int x){for(int y=0;x;y=x,x=pa) splay(x),r=y,update(x);}//将当前节点至根的路径修改为一条重链
void makeroot(int x){access(x);splay(x);reverse(x);}//将x换为原树的根
int findroot(int x)//查询节点x所在树的根
{
access(x);splay(x);
while(l) pushdown_once(x),x=l;return x;
}
void link(int x,int y){makeroot(x);T[x].fa=y;}//将x接在y下方(反着接也可以)
void cut(int x,int y)//断开x,y的连接
{
makeroot(x);access(y);splay(y);
T[x].fa=T[y].ch[0]=0;update(y);
}
void split(int x,int y){makeroot(x);access(y);splay(y);}
}st;
int main()
{
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&st.T[i].w);
for(int i=1;i<=m;i++)
{
int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
if(opt==0) st.split(x,y),printf("%d\n",st.T[y].sum);
if(opt==1) if (st.findroot(x)!=st.findroot(y)) st.link(x,y);
if(opt==2) if (st.findroot(x)==st.findroot(y)) st.cut(x,y);
if(opt==3) st.T[x].w=y,st.splay(x);
}
return 0;
}
以上是关于luogu3690 模板Link Cut Tree (动态树)的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3690模板Link Cut Tree(动态树)
[lct] Luogu P3690模板Link Cut Tree (动态树)