MnZn lct 5pts 求调
查看原帖
MnZn lct 5pts 求调
307535
Custlo0793楼主2022/8/16 10:38

最后一个点 qwq.

#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#define int long long
#define ls son[u][0]
#define rs son[u][1]
#define add(x, y) x = (x + y) % MOD
#define mul(x, y) x = (x * y) % MOD
 
using namespace std;

const int N = 1e5 + 5, inf = 1e9 + 5, MOD = 51061;

int n, m, a[N];

namespace LCT {
	int fa[N], son[N][2], s[N], siz[N], st[N], ad[N], ml[N];
	bool rev[N];
	inline bool isr (int u) { return son[fa[u]][0] == u || son[fa[u]][1] == u;}
	inline void pushup (int u) { s[u] = (s[ls] + s[rs] + a[u]) % MOD, siz[u] = siz[ls] + siz[rs] + 1; }
	inline void getrev (int u) { swap(ls, rs), rev[u] ^= 1; }
	inline void getad (int u, int c) { add(s[u], c * siz[u]), add(a[u], c), add(ad[u], c); }
	inline void getml (int u, int c) { mul(s[u], c), mul(a[u], c), mul(ml[u], c), mul(ad[u], c); }
	inline void pushdown (int u) {
	    if (ml[u] != 1) getml(ls, ml[u]), getad(rs, ml[u]), ml[u] = 1;
		if (ad[u]) getad(ls, ad[u]), getad(rs, ad[u]), ad[u] = 0;
		if (rev[u]) {
			if (ls) getrev(ls);
			if (rs) getrev(rs);
			rev[u] = 0;
		}
	}
	inline void rotate (int u) {
		int y = fa[u], z = fa[y], f = son[y][1] == u, g = son[u][! f];
		if (isr(y)) son[z][son[z][1] == y] = u;
	    son[u][! f] = y, son[y][f] = g;
		if (g) fa[g] = y;
		fa[y] = u, fa[u] = z, pushup(y);
	} 
	inline void splay (int u) {
		int v = u, w, top = 0;
		st[++ top] = v;
		while (isr(v)) st[++ top] = v = fa[v];
		while (top) pushdown(st[top --]);
		while (isr(u)) {
			v = fa[u], w = fa[v];
			if (isr(v)) rotate((son[v][0] == u) ^ (son[w][0] == v) ? u : v);
			rotate(u);
		}
		pushup(u);
	}
	inline void access (int u) { for (int v = 0; u; u = fa[v = u]) splay(u), rs = v, pushup(u); }
	inline void makert (int u) { access(u), splay(u), getrev(u); }
	inline void split (int u, int v) { makert(u), access(v), splay(v); }
	inline int getrt (int u) {
		access(u), splay(u);
		while (ls) pushdown(u), u = ls;
		splay(u); return u;
	}
	inline void link (int u, int v) {
		makert(u);
		if (getrt(v) != u) fa[u] = v;
	} // void -> bool -> existed
	inline void cut (int u, int v) {
		makert(u);
		if (getrt(v) == u && fa[v] == u && ! son[v][0])
		fa[v] = rs = 0, pushup(u);
	} // void -> bool -> existed
} 

signed main() {
    ios ::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) a[i] = LCT::siz[i] = LCT::ml[i] = 1;
    for (int i = 1, u, v; i < n; i ++)
    	cin >> u >> v, LCT::link(u, v);
    for (int i = 1; i <= m; i ++) {
    	char opt;
    	int u, v, k;
    	cin >> opt;
    	if (opt == '+') {
    		cin >> u >> v >> k;
    		LCT::split(u, v), LCT::getad(v, k);
		}
    	else if (opt == '-') {
    		cin >> u >> v, LCT::cut(u, v);
    		cin >> u >> v, LCT::link(u, v);
		}
    	else if (opt == '*') {
    		cin >> u >> v >> k;
    		LCT::split(u, v), LCT::getml(v, k);
		}
    	else if (opt == '/') {
    		cin >> u >> v;
    		LCT::split(u, v), cout << LCT::s[v]<<endl;
		}
    }
    return 0;
}
2022/8/16 10:38
加载中...