luogu P3690模板Link Cut Tree(动态树)

Posted lordxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P3690模板Link Cut Tree(动态树)相关的知识,希望对你有一定的参考价值。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
	while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 3e5 + 10;
int n, m;
struct node {
	int ch[2], fa, lazy, val;
}tree[N];
int val[N];
int ident(int rt,int fa) {
	return tree[fa].ch[1] == rt;
}
void connect(int rt, int fa,int son)
{
	tree[rt].fa = fa;
	tree[fa].ch[son] = rt;
}
bool isroot(int rt)
{
	int f = tree[rt].fa;
	return tree[f].ch[1] != rt && tree[f].ch[0] != rt;
}
void pushup(int rt) {
	int ls = tree[rt].ch[0];
	int rs = tree[rt].ch[1];
	tree[rt].val = tree[ls].val^tree[rs].val ^ val[rt];
}
void rev(int x)
{
	swap(tree[x].ch[0], tree[x].ch[1]);
	tree[x].lazy ^= 1;
}
void pushdown(int rt)
{
	if (tree[rt].lazy)
	{
		if (tree[rt].ch[0])rev(tree[rt].ch[0]);
		if (tree[rt].ch[1])rev(tree[rt].ch[1]);
		tree[rt].lazy = 0;
	}
}
void pushall(int rt)
{
	if (!isroot(rt))pushall(tree[rt].fa);
	pushdown(rt);
}
void rotate(int rt)
{
	int f = tree[rt].fa; int ff = tree[f].fa; int k = ident(rt, f);
	connect(tree[rt].ch[k ^ 1], f, k);
	tree[rt].fa = ff;
	if (!isroot(f))tree[ff].ch[ident(f, ff)] = rt;
	connect(f, rt, k ^ 1);
	pushup(f); pushup(rt);
}
void splay(int x)
{
	pushall(x);
	while (!isroot(x))
	{
		int f = tree[x].fa; int ff = tree[f].fa;
		if (!isroot(f))
			ident(f, ff) ^ ident(x, f) ? rotate(x) : rotate(f);
		rotate(x);
	}
}
void access(int x)
{
	for (int y = 0; x; x = tree[x].fa)
	{
		splay(x);
		tree[x].ch[1] = y;
		pushup(x);        
		y = x;
	}
}
void makeroot(int x)
{
	access(x); splay(x); rev(x);
}
int findroot(int x)
{
	access(x); splay(x);
	while (tree[x].ch[0]) {
		pushdown(x);
		x = tree[x].ch[0];
	}
	splay(x);
	return x;
}
void link(int x,int y)
{
	makeroot(x);
	if (findroot(y) != x)tree[x].fa = y;
}
void cut(int x, int y)
{
	makeroot(x);
	if (findroot(y) != x || tree[y].fa != x || tree[y].ch[0])return;
	tree[y].fa = tree[x].ch[1] = 0;
	pushup(x);
}
void split(int x, int y)
{
	makeroot(x);
	access(y);
	splay(y);
}
int main()
{
#ifdef local
	freopen("D:++P3690_9.in", "r", stdin);
	freopen("D:++P3369_2.out", "w", stdout);
#endif // 

	n = read(), m = read();
	upd(i, 1, n)tree[i].val = read(), val[i] = tree[i].val;
	int op, xx, yy;
	while (m--)
	{
		op = read();
		xx = read(), yy = read();
		if (op == 0)
		{
			split(xx, yy);
			printf("%d
", tree[yy].val);
		}
		else if (op == 1)
		{
			link(xx, yy);
		}
		else if (op == 2)
		{
			cut(xx, yy);
		}
		else if (op == 3)
		{
			splay(xx);
			val[xx] = yy;
			pushup(xx);
		}
	}
	return 0;
}

以上是关于luogu P3690模板Link Cut Tree(动态树)的主要内容,如果未能解决你的问题,请参考以下文章

P3690 模板Link Cut Tree (动态树)

luogu P3690 ????????????Link Cut Tree ???????????????

P3690 模板Link Cut Tree (动态树)

AC日记——模板Link Cut Tree 洛谷 P3690

P3690 模板Link Cut Tree (动态树)

P3690 模板Link Cut Tree (动态树)