lct 基础(' ' ) 就当个纪念吧(' ' ) 毕竟写了4h, cut 部分一直naive 总是想找谁是儿子,然后最后发现直接提根就好了啊(' ' )
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const ll mod = 51061; const ll maxn = 100010; ll pl(ll a, ll b) { ll ret = a + b; if(ret >= mod) ret %= mod; return ret; } ll mul(ll a, ll b) { return a * b % mod; } struct node { ll ans, lm, lp, lr, size, data, p; node *son[2], *fa; }e[maxn]; ll ne = 0; void test(node* x) { if(!x) return; cout << x-> data <<" "<<x-> size <<" "<< x-> p << endl; for(ll i = 0; i < 2; ++ i) test(x-> son[i]); } void update(node* x) { x-> ans = x-> data, x-> size = 1; for(ll i = 0; i < 2; ++ i) if(x-> son[i]) x-> ans = pl(x-> ans, x-> son[i]-> ans), x-> size = pl(x-> son[i]-> size, x-> size); } void swap(node* &a, node* &b) { node* mid = a; a = b, b = mid; } void pushdown(node* x) { if(!x || (!x-> lp && !x-> lr && x-> lm == 1)) return; if(x-> lr) { swap(x-> son[0], x-> son[1]); for(ll i = 0; i < 2; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= 1; x-> lr = 0; } for(ll i = 0; i < 2; ++ i) { if(x-> son[i]) { x-> son[i]-> ans = pl(mul(x-> son[i]-> ans, x-> lm), mul(x-> son[i]-> size, x-> lp)); x-> son[i]-> data = pl(mul(x-> son[i]->data, x-> lm), x-> lp); x-> son[i]-> lp = pl(mul(x-> son[i]-> lp, x-> lm), x-> lp); x-> son[i]-> lm = mul(x-> son[i]-> lm, x-> lm); } } x-> lm = 1, x-> lp = 0; } void rotate(node* x, ll f) { node* y = x-> fa; if(y-> fa) { if(y-> fa-> son[0] == y) y-> fa-> son[0] = x; else y-> fa-> son[1] = x; } x-> fa = y-> fa; x-> size = y-> size; y-> fa = x; x-> p = y-> p; x-> ans = y-> ans; y-> son[f] = x-> son[!f]; if(x-> son[!f]) x-> son[!f]-> fa = y; x-> son[!f] = y; update(y); } void splay(node* x, node* f) { pushdown(x); while(x-> fa != f) { if(x-> fa-> fa == f) { pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x); ll a = x-> fa-> son[0] == x ? 0 : 1; rotate(x, a); } else { node *y = x-> fa, *z = y-> fa; pushdown(z), pushdown(y), pushdown(x); ll a = z-> son[0] == y ? 0 : 1; ll b = y-> son[0] == x ? 0 : 1; if(a == b) rotate(y, a), rotate(x, b); else rotate(x, b), rotate(x, a); } } } void access(ll cur) { node* x = e + cur; pushdown(x); node* y; splay(x, NULL); if(x-> son[1]) x-> son[1]-> p = cur, x-> son[1]-> fa = NULL, x-> son[1] = NULL; update(x); ll pp; while((pp = x-> p)) { y = e + pp; splay(y, NULL); if(y-> son[1]) y-> son[1]-> p = pp, y-> son[1]-> fa = NULL, y-> son[1] = NULL; y-> son[1] = x; x-> fa = y; update(y); splay(x, NULL); } } void reserve(ll x) { access(x); //test(x + e); cout << endl; (e + x)-> lr ^= 1; } ll n, m; void link(ll a, ll b) { access(a); reserve(b); (e + b)-> p = a; update(e + a), update(e + b); } void cut(ll a, ll b) { reserve(a), access(b); //test(b + e); cout << endl; (e + a)-> p = 0, (e + a)-> fa = NULL, (e + b)-> son[0] = NULL; update(e + a), update(e + b); } ll ll_get() { ll x = 0; char c = (char)getchar(); while(!isdigit(c) && c != '-') c = (char)getchar(); bool f = 0; if(c == '-') f = 1, c = (char)getchar(); while(isdigit(c)) { x = x * 10 + (ll)(c - '0'); c = (char)getchar(); } if(f) x = -x; return x; } struct edge { ll t; edge* next; }se[maxn * 2], *head[maxn]; ll oe = 0; void addedge(ll f, ll t) { se[oe].t = t, se[oe].next = head[f], head[f] = se + oe ++; } bool vis[maxn]; void build(ll x, ll pre) { vis[x] = 1; (e + x)-> p = pre; (e + x)-> data = (e + x)-> ans = 1; (e + x)-> size = 1; (e + x)-> lm = 1; for(edge* p = head[x]; p; p = p-> next) { if(!vis[p-> t]) build(p-> t, x); } } void read() { n = ll_get(), m = ll_get(); for(ll i = 1; i < n; ++ i) { ll f = ll_get(), t = ll_get(); addedge(f, t), addedge(t, f); } memset(vis, 0, sizeof(vis)); build(1, 0); } void sov() { char s[10]; // for(int i = 1; i <= n; ++ i) test(e + i), cout << endl; //cout << "****\n"; while(m --) { scanf("%s", s + 1); if(s[1] == '+') { ll a = ll_get(), b = ll_get(), c = ll_get(); reserve(a); access(b); node* x = (e + b); x-> lp = pl(c, x-> lp), x-> ans = pl(x-> ans, mul(c, x-> size)), x-> data = pl(x-> data, c); } if(s[1] == '*') { ll a = ll_get(), b = ll_get(), c = ll_get(); reserve(a); access(b); node* x = (e + b); x-> lm = mul(x-> lm, c), x-> ans = mul(x-> ans, c), x-> data = mul(x-> data, c), x-> lp = mul(x-> lp, c); } if(s[1] == '-') { ll a, b, c, d; a = ll_get(), b = ll_get(), c = ll_get(), d = ll_get(); cut(a, b); //for(int i = 1; i <= n; ++ i) cout << (e + i)-> p << endl<< endl; //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl; //cout << "****\n"; link(c, d); //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl; } if(s[1] == '/') { ll a, b; a = ll_get(), b = ll_get(); reserve(a), access(b); printf("%lld\n", (e + b)-> ans); } //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl; //cout << "****\n"; //cout << (e + 1)-> son[0] << endl; } } int main() { //freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); read(); sov(); }