lct 0pts 求调 玄关
查看原帖
lct 0pts 求调 玄关
1023865
xuezhiyu楼主2024/12/31 22:24
#include <iostream>
#define int long long
#define endl '\n'

using namespace std;

constexpr int N = 1e5 + 10, mod = 51061;
bool tagrev[N];
int n, m, ch[N][2], fa[N], val[N], sum[N], siz[N], tagmul[N], tagadd[N];

int where(int x) { return ch[fa[x]][1] == x; }

bool isroot(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }

void print() {
	for (int i = 0; i <= n; i++) cout << i << ": val=" << val[i] << ", sum=" << sum[i] << ", ch=[" << ch[i][0] << ", " << ch[i][1] << "], fa=" << fa[i] << ", tag=[ + " << tagadd[i] << ", * " << tagmul[i] << ", rev " << tagrev[i] << "]" << endl;
}

void pushup(int x) {
	siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
	sum[x] = (sum[ch[x][0]] + val[x] + sum[ch[x][1]]) % mod;
}

void pushdown(int x) {
	if (tagrev[x]) {
		if (ch[x][0]) swap(ch[ch[x][0]][0], ch[ch[x][0]][1]), tagrev[ch[x][0]] = !tagrev[ch[x][0]];
		if (ch[x][1]) swap(ch[ch[x][1]][0], ch[ch[x][1]][1]), tagrev[ch[x][1]] = !tagrev[ch[x][1]];
		tagrev[x] = false;
	}
	val[ch[x][0]] = (val[ch[x][0]] * tagmul[x] % mod + tagadd[x]) % mod;
	val[ch[x][1]] = (val[ch[x][1]] * tagmul[x] % mod + tagadd[x]) % mod;
	sum[ch[x][0]] = (sum[ch[x][0]] * tagmul[x] % mod + siz[ch[x][0]] * tagadd[x] % mod) % mod;
	sum[ch[x][1]] = (sum[ch[x][1]] * tagmul[x] % mod + siz[ch[x][1]] * tagadd[x] % mod) % mod;
	tagmul[ch[x][0]] = tagmul[ch[x][0]] * tagmul[x] % mod, tagmul[ch[x][1]] = tagmul[ch[x][1]] * tagmul[x] % mod;
	tagadd[ch[x][0]] = (tagadd[ch[x][0]] * tagmul[x] % mod + tagadd[x]) % mod;
	tagadd[ch[x][1]] = (tagadd[ch[x][1]] * tagmul[x] % mod + tagadd[x]) % mod;
	tagmul[x] = 1, tagadd[x] = 0;
}

void pushdownall(int x) {
	if (!isroot(x)) pushdownall(fa[x]);
	pushdown(x);
}

void rotate(int x) {
	if (isroot(x)) return;
	int y = fa[x], z = fa[fa[x]], chk = where(x);
 	if (!isroot(y)) ch[z][where(y)] = x;
	ch[y][chk] = ch[x][chk ^ 1];
	if (ch[x][chk ^ 1]) fa[ch[x][chk ^ 1]] = y;
	ch[x][chk ^ 1] = y, fa[y] = x, fa[x] = z;
	pushup(y), pushup(x);
}

void splay(int x) {
	pushdownall(x);
	for (int y; y = fa[x], !isroot(x); rotate(x))
		if (!isroot(y)) rotate(where(y) == where(x) ? y : x);
}

void access(int x) {
	int y = 0;
	while (x) {
		splay(x);
		ch[x][1] = y;
		pushup(x);
		y = x, x = fa[x];
	}
}

void beroot(int x) {
	access(x), splay(x);
	swap(ch[x][0], ch[x][1]);
	tagrev[x] = !tagrev[x];
}

void belink(int x, int y) {
	beroot(x);
	access(y);
	splay(y);
}

int findRoot(int x) {
	access(x), splay(x);
	while (ch[x][0]) x = ch[x][0];
	splay(x);
	return x;
}

void link(int x, int y) {
	if (findRoot(x) != findRoot(y)) beroot(x), fa[x] = y;
}

void cut(int x, int y) {
	belink(x, y);
	if (ch[y][0] == x) ch[y][0] = fa[x] = 0;
}

void updatemul(int x, int y, int v) {
	belink(x, y);
	val[x] = val[x] * v % mod, sum[x] = sum[x] * v % mod, tagmul[x] = tagmul[x] * v % mod, tagadd[x] = tagadd[x] * v % mod;
}

void updateadd(int x, int y, int v) {
	belink(x, y);
	val[x] = (val[x] + v) % mod, sum[x] = (sum[x] + siz[x] * v % mod) % mod, tagadd[x] = (tagadd[x] + v) % mod;
}

int query(int x, int y) {
	belink(x, y);
	return sum[y];
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		tagmul[i] = 1;
		val[i] = 1;
		pushup(i);
	}
	for (int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		link(u, v);
	}
	while (m --> 0) {
		char opt;
		cin >> opt;
		if (opt == '+') {
			int x, y, v;
			cin >> x >> y >> v;
			updateadd(x, y, v);
		} else if (opt == '-') {
			int u1, v1, u2, v2;
			cin >> u1 >> v1 >> u2 >> v2;
			cut(u1, v1), link(u2, v2);
		} else if (opt == '*') {
			int x, y, v;
			cin >> x >> y >> v;
			updatemul(x, y, v);
		} else if (opt == '/') {
			int u, v;
			cin >> u >> v;
			cout << query(u, v) << endl;
		} else {
			int u, v;
			cin >> u >> v;
			link(u, v);
		}
	}
	return 0;
}
2024/12/31 22:24
加载中...