萌新求助LCT 样例过了0pts Thanks♪(・ω・)ノ
查看原帖
萌新求助LCT 样例过了0pts Thanks♪(・ω・)ノ
519384
Link_Cut_Y楼主2022/2/14 15:13
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define ls tr[x].s[0]
#define rs tr[x].s[1]

using namespace std;

const int N = 200010;

int n, m;

struct Tree
{
	int s[2], v, p;
	int rev, sum, minn, maxn;
	int opposite;
}tr[N << 1];

void push_rev(int x)
{
	swap(ls, rs);
	tr[x].rev ^= 1;
}

void push_opposite(int x)
{
	swap(tr[x].maxn, tr[x].minn);
	tr[x].maxn = -tr[x].maxn;
	tr[x].minn = -tr[x].minn;
	tr[x].v = -tr[x].v;
	tr[x].sum = -tr[x].sum;
	tr[x].opposite ^= 1;
}

void pushup(int x)
{
	tr[x].sum = tr[ls].sum + tr[rs].sum + tr[x].v;
	tr[x].minn = min(tr[x].v, min(tr[ls].minn, tr[rs].minn));
	tr[x].maxn = max(tr[x].v, max(tr[ls].maxn, tr[rs].maxn));
}

void pushdown(int x)
{
	if (tr[x].opposite)
	{
		push_opposite(ls), push_opposite(rs);
		tr[x].opposite = 0;
	}
	
	if (tr[x].rev)
	{
		push_rev(ls), push_rev(rs);
		tr[x].rev = 0;
	}
}

bool is_root(int x)
{
	return tr[tr[x].p].s[1] != x && tr[tr[x].p].s[0] != x;
}

void push_all(int x)
{
	if (!is_root(x)) push_all(tr[x].p);
	pushdown(x);
}

void rotate(int x)
{
	int y = tr[x].p, z = tr[y].p;
	int k = tr[y].s[1] == x;
	
	if (!is_root(y)) tr[z].s[tr[z].s[1] == y] = x; tr[x].p = z;
	tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
	tr[x].s[k ^ 1] = y, tr[y].p = x;
	
	pushup(y), pushup(x);
}

void splay(int x)
{
	push_all(x);
	
	while (!is_root(x))
	{
		int y = tr[x].p, z = tr[y].p;
		if (!is_root(y)) rotate(((tr[y].s[1] == x) ^ (tr[z].s[1] == y)) ? x : y);
		rotate(x);
	}
}

void access(int x)
{
	for (int y = 0; x; y = x, x = tr[x].p)
	{
		splay(x);
		tr[x].s[1] = y;
		pushup(x);
	}
}

void make_root(int x)
{
	access(x);
	splay(x);
	push_rev(x);
}

void make_path(int x, int y)
{
	make_root(x);
	access(y);
	splay(x);
}

void link(int x, int y)
{
	make_root(x);
	tr[x].p = y;
}

int main()
{
//	freopen("traval.in", "r", stdin);
//	freopen("traval.out", "w", stdout);
	
	scanf("%d", &n);
	
	for (int i = 0; i < n + n - 1; i ++ )
		tr[i].maxn = -0x3f3f3f3f, tr[i].minn = 0x3f3f3f3f;
		
	for (int i = 1; i <= n - 1; i ++ )
	{
		int u, v;
		scanf("%d%d%d", &u, &v, &tr[n + i].v);
		u ++ , v ++ ;
		tr[n + i].maxn = tr[n + i].minn = tr[n + i].v;
		link(u, n + i), link(n + i, v);
	}
	
	scanf("%d", &m);
	
	while (m -- )
	{
		char op[4];
		int x, y;
		scanf("%s%d%d", op, &x, &y);
		
		if (*op == 'C') splay(n + x), tr[n + x].v = y, pushup(n + x);
		if (*op == 'N') x ++ , y ++ , make_path(x, y), push_opposite(x);
		if (*op == 'S') x ++ , y ++ , make_path(x, y), printf("%d\n", tr[x].sum);
		if (*op == 'M' && op[1] == 'A') x ++ , y ++ , make_path(x, y), printf("%d\n", tr[x].maxn);
		if (*op == 'M' && op[1] == 'I') x ++ , y ++ , make_path(x, y), printf("%d\n", tr[x].minn);
	}
	
	return 0;
}
2022/2/14 15:13
加载中...