4kb200行主席树+树剖 RE+TLE 不帮忙也进来看个乐子
查看原帖
4kb200行主席树+树剖 RE+TLE 不帮忙也进来看个乐子
1198462
dvsfanjo楼主2025/7/21 20:55

rt 本人袜子

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 5, p = 20160501, inv = 10080251;
ll dep[maxn], val[maxn], ide[maxn], son[maxn], top[maxn], siz[maxn], fat[maxn], a[maxn], b[maxn], sum[maxn][2];
vector <ll> G[maxn];
ll ver[maxn], rt, op, x, y, w, vers, lst, num, n, q, u, v, cnt;
void dfs1(ll u, ll fa) {
    fat[u] = fa;
    dep[u] = dep[fa] + 1;
    siz[u] = 1;
    for (auto g : G[u]) {
        if (g == fa) continue;
        dfs1(g, u);
        siz[u] += siz[g];
        if (siz[g] > siz[son[u]]) son[u] = g;
    }
}
void dfs2(ll u, ll T) {
    ide[u] = ++cnt;
    top[u] = T;
    a[cnt] = val[u];
    b[cnt] = dep[u];
    if (son[u]) dfs2(son[u], T);
    for (auto g : G[u]) {
        if (g == fat[u] || g == son[u]) continue;
        dfs2(g, g);
    }
}
struct node {
    ll sum, smul, spow, tag;
    ll ls, rs, lv, rv;
    inline void out() {
    	cout << sum << ' ' << smul << ' ' << spow << ' ' << tag << ' ' << ls << ' ' << rs << ' ' << lv << ' ' << rv << '\n';
	}
    friend node operator + (node a, node b) {
        return node{
            (a.sum + b.sum) % p,
            (a.smul + b.smul) % p,
            (a.spow + b.spow) % p,
            0, 0, 0, 0, 0};
    }
} t[maxn << 6];
ll tot;
#define mid (l + r >> 1)
void build(ll l, ll r, ll &u) {
    u = ++tot;
    if (l == r) {
        t[u] = {
            a[l],
            a[l] * b[l] % p,
            a[l] * b[l] % p * b[l] % p,
            0, 0, 0, 0, 0};
        sum[l][0] = (sum[l - 1][0] + b[l]) % p;
        sum[l][1] = (sum[l - 1][1] + b[l] * b[l] % p) % p;
    } else {
        build(l, mid, t[u].ls);
        build(mid + 1, r, t[u].rs);
        node c = t[t[u].ls] + t[t[u].rs];
        t[u].sum  = c.sum;
        t[u].smul = c.smul;
        t[u].spow = c.spow;
    } return;
}
inline ll clone(ll u) {
    t[++tot] = t[u];
    t[tot].lv = t[tot].rv = false;
    return tot;
}
inline void pushup(ll l, ll r, node &x, ll k) {
    x.sum  = (x.sum  + (r - l + 1) * k % p) % p;
    x.smul = (x.smul + (sum[r][0] - sum[l - 1][0] + p) % p * k % p) % p;
    x.spow = (x.spow + (sum[r][1] - sum[l - 1][1] + p) % p * k % p) % p;
    return;
}
void update(ll l, ll r, ll u, ll a, ll b, ll k) {
    pushup(max(l, a), min(r, b), t[u], k);
    if (a <= l && r <= b) {
        t[u].tag = (t[u].tag + k) % p;
    } else {
        if (a <= mid) {
            if (!t[u].lv) {
                t[u].ls = clone(t[u].ls);
                t[u].lv = true;
                t[t[u].ls].lv = t[t[u].ls].rv = false;
            } update(l, mid, t[u].ls, a, b, k);
        }
        if (mid < b) {
            if (!t[u].rv) {
                t[u].rs = clone(t[u].rs);
                t[u].rv = true;
                t[t[u].rs].lv = t[t[u].rs].rv = false;
            } update(mid + 1, r, t[u].rs, a, b, k);
        }	
    } return;
}
node query(ll l, ll r, ll u, ll a, ll b) {
    if (a <= l && r <= b) {
        return t[u];
    } else {
        node res = {0, 0, 0, 0, 0, 0, 0, 0};
        pushup(max(l, a), min(r, b), res, t[u].tag);
        if (a <= mid) res = res + query(l, mid, t[u].ls, a, b);
        if (mid < b)  res = res + query(mid + 1, r, t[u].rs, a, b);
        return res;
    }
}
void lca_update(ll rt, ll u, ll v, ll k) {
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) {
            update(1, n, ver[rt], ide[top[u]], ide[u], k);
            u = fat[top[u]];
        } else {
            update(1, n, ver[rt], ide[top[v]], ide[v], k);
            v = fat[top[v]];
        }
    }
    if (dep[u] > dep[v]) swap(u, v);
    update(1, n, ver[rt], ide[u], ide[v], k);
}
ll lca(ll u, ll v) {
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) {
            u = fat[top[u]];
        } else {
            v = fat[top[v]];
        }
    }
    return dep[u] < dep[v] ? u : v;
}
inline ll A(ll l, ll r, ll rt, ll deplca, ll depv) {
    if (l > r) return 0;
    node ret = query(1, n, ver[rt], l, r);
    ll res = ret.spow;
    res = (res + (2 * depv - 4 * deplca + 1) * ret.smul % p) % p;
    res = (res + (4 * deplca * deplca + depv - 4 * deplca * depv - 2 * deplca + p) % p * ret.sum % p) % p;
    return res;
}
inline ll B(ll l, ll r, ll rt, ll deplca, ll depv) {
    if (l > r) return 0;
    node ret = query(1, n, ver[rt], l, r);
    ll res = ret.spow;
    res = (res - (2 * depv + 1) * ret.smul % p + p) % p;
    res = (res + (depv * depv + depv) * ret.sum % p) % p;
    return res;
}
ll lca_query(ll rt, ll u, ll v) {
    ll res = 0, Lca = lca(u, v), depv = dep[v];
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) {
            res = (res + A(ide[top[u]], ide[u], rt, dep[Lca], depv)) % p;
            u = fat[top[u]];
        } else {
            res = (res + B(ide[top[v]], ide[v], rt, dep[Lca], depv)) % p;
            v = fat[top[v]];
        }
    }
    if (dep[u] >= dep[v]) {
    	res = (res + A(ide[v], ide[u], rt, dep[Lca], depv)) % p;
    	//cout << "A " << ide[v] << ' ' << ide[u] << '\n';
	} else {
		res = (res + B(ide[u], ide[v], rt, dep[Lca], depv)) % p;
		//cout << "B " << ide[u] << ' ' << ide[v] << '\n'; 
	} return res * inv % p;
}
void DEBUG() {
	for (int i = 1; i <= n; i++) {
		node res = query(1, n, ver[rt], i, i);
		cout << res.sum << ' ' << res.smul << ' ' << res.spow << '\n';
	} cout << '\n';
}
void dfs(ll l, ll r, ll u) {
	cout << '[' << l << ',' << r << "]:" << u << ' '; t[u].out();
	if (l == r) return;
	dfs(l, mid, t[u].ls); dfs(mid + 1, r, t[u].rs);
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> n >> q;
    for (int i = 1; i < n; i++) {
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        cin >> val[i];
    }
    dfs1(1, 0); dfs2(1, 1);
    build(1, n, ver[0]);
    //DEBUG();
    while (q--) {
        cin >> op;
        if (op == 1) {
            cin >> x >> y >> w;
            x ^= lst; y ^= lst;
            ll nwrt = clone(ver[rt]);
            ver[++vers] = nwrt;
            rt = vers;
            t[ver[rt]].lv = t[ver[rt]].rv = false;
            lca_update(rt, x, y, w);
        }
        if (op == 2) {
            cin >> x >> y;
            x ^= lst; y ^= lst;
            lst = lca_query(rt, x, y);
            cout << lst << '\n';
        }
        if (op == 3) {
            cin >> x;
            x ^= lst;
            rt = x;
        } //DEBUG();
    }
    return 0;
}
/*
5 6
1 2
2 3
3 4
4 5
1 2 3 4 5
1 1 5 2
3 0
1 1 3 2
1 3 4 2
3 2
2 1 5

73

time0 ver0:
1 2 3 4 5
1 4 9 16 25
1 8 27 64 125

time1 ver1:
3 4 5 6 7
3 8 15 64 35
3 16 45 96 175

time2 ver0:
1 2 3 4 5
1 4 9 16 25
1 8 27 64 125

time3 ver2:
3 4 5 4 5
3 8 15 16 25
3 16 45 64 125

time4 ver3:
3 4 7 6 5
3 8 21 24 25
3 16 63 96 125

time5 ver2:
3 4 5 4 5
3 8 15 16 25
3 16 45 64 125

time6 ver2:
3 4 5 4 5
3 8 15 16 25
3 16 45 64 125

3 4 5 4 5

3 * 4 * 5 + 4 * 3 * 4 + 5 * 2 * 3 + 4 * 1 * 2 = 60 + 48 + 30 + 8 = 146
*/
2025/7/21 20:55
加载中...