刚学OI的萌新求助简单树上问题

P3703 [SDOI2017] 树点涂色

哦代码粘的不是最新版()。 ```cpp #include <bits/stdc++.h> using namespace std; #define int long long #define endl "\n" #define lc(x) (x<<1) #define rc(x) (x<<1|1) #define pii pair<int,int> #define p1(x) (x).first #define p2(x) (x).second int n, q; int C[200300]; int xc[200300]; vector<int>g[100300]; int d[100300], f[100300], tp[100300], dfn[100300], siz[100300], loc[100300], hs[100300]; map<int, int>mp[100300]; struct node { int s, lid, rid, mx, cnt, tgmx, tgid; friend node operator +(const node A, const node B) { if (A.s == -1) return B; if (B.s == -1) return A; return {A.s + B.s, A.lid, B.rid, max(A.mx, B.mx), A.cnt + B.cnt - (A.rid == B.lid), 0, 0}; } inline void add_mx(int x) { tgmx += x; mx += x; } inline void cover_id(int x) { tgid = x; lid = rid = x; cnt = 1; } } T[100300 << 2]; inline void upd(int x) { T[x] = T[lc(x)] + T[rc(x)]; } inline void pd(int x) { if (T[x].tgmx) { T[lc(x)].add_mx(T[x].tgmx); T[rc(x)].add_mx(T[x].tgmx); T[x].tgmx = 0; } if (T[x].tgid) { T[lc(x)].cover_id(T[x].tgid); T[rc(x)].cover_id(T[x].tgid); T[x].tgid = 0; } } int col = 0; inline void bd(int x, int l, int r) { if (l == r) { T[x] = {1, loc[l], loc[l], d[loc[l]], 1, 0, 0}; return ; } int mid = l + r >> 1; bd(lc(x), l, mid); bd(rc(x), mid + 1, r); upd(x); } inline void cov(int x, int l, int r, int L, int R, int c) { if (L <= l && r <= R) { T[x].cover_id(c); return ; } pd(x); int mid = l + r >> 1; if (L <= mid) cov(lc(x), l, mid, L, R, c); if (R > mid) cov(rc(x), mid + 1, r, L, R, c); upd(x); } inline void add(int x, int l, int r, int L, int R, int c) { if (L <= l && r <= R) { T[x].add_mx(c); return ; } pd(x); int mid = l + r >> 1; if (L <= mid) add(lc(x), l, mid, L, R, c); if (R > mid) add(rc(x), mid + 1, r, L, R, c); upd(x); } queue<int>Q; inline node gt(int x, int l, int r, int L, int R) { if (L <= l && r <= R) return T[x]; pd(x); int mid = l + r >> 1; bool lp = L <= mid, rp = R > mid; if (lp && rp) return gt(lc(x), l, mid, L, R) + gt(rc(x), mid + 1, r, L, R); if (lp) return gt(lc(x), l, mid, L, R); if (rp) return gt(rc(x), mid + 1, r, L, R); assert(0); } inline void ADD(int x, int k) { // cout<<x<<" "<<k<<endl; // if(k==1){ // cout<<x<<" "; // } // else cout<<"!"<<endl; add(1, 1, n, dfn[x], dfn[x] + siz[x] - 1, k); // if(k==1){ // cout<<gt(1,1,n,dfn[791],dfn[791]).mx<<endl; // } } inline void ers(int x, int l, int r, int L, int R) { if (T[x].s == 0) return ; if (l == r) { T[x].s = 0; Q.push(loc[l]); return ; } pd(x); int mid = l + r >> 1; if (L <= mid) ers(lc(x), l, mid, L, R); if (R > mid) ers(rc(x), mid + 1, r, L, R); upd(x); } inline void ins(int x, int l, int r, int c) { if (l == r) { if (T[x].s) return ; T[x].s = 1; return ; } pd(x); int mid = l + r >> 1; if (c <= mid) ins(lc(x), l, mid, c); else ins(rc(x), mid + 1, r, c); upd(x); } int tk; inline void dfs(int u) { siz[u] = 1; d[u] = d[f[u]] + 1; for (int v : g[u]) if (v != f[u]) { f[v] = u; dfs(v); siz[u] += siz[v]; if (siz[v] > siz[hs[u]]) hs[u] = v; } } inline void dfs(int u, int t) { tp[u] = t; loc[dfn[u] = ++tk] = u; if (hs[u]) dfs(hs[u], t); for (int v : g[u]) if (v != f[u] && v != hs[u]) dfs(v, v); for (int v : g[u]) if (v != f[u]) mp[u][dfn[v] + siz[v] - 1] = v; } inline node rev(node A) { swap(A.lid, A.rid); return A; } inline int LCA(int x, int y) { while (tp[x] != tp[y]) { if (d[tp[x]] < d[tp[y]]) swap(x, y); x = f[tp[x]]; } if (d[x] < d[y]) swap(x, y); return y; } inline void mod(int x, int c) { xc[c] = x; while (x) { cov(1, 1, n, dfn[tp[x]], dfn[x], c); ers(1, 1, n, dfn[tp[x]], dfn[x]); x = f[tp[x]]; } ADD(1, 1); ins(1, 1, n, dfn[1]); C[1] = c; x = xc[c]; while (!Q.empty()) { int lc = Q.front(), c = C[lc]; Q.pop(); ADD(lc, -1); int L = LCA(x, xc[c]); if (L == xc[c]) { xc[c] = -1; continue; } L = mp[L].lower_bound(dfn[xc[c]])->second; // cout<<c<<" "; C[L] = c; ins(1, 1, n, dfn[L]); } } inline node gt(int x, int y) { node X, Y; X.s = Y.s = -1; while (tp[x] != tp[y]) { if (d[tp[x]] > d[tp[y]]) { X = X + rev(gt(1, 1, n, dfn[tp[x]], dfn[x])); x = f[tp[x]]; } else { Y = gt(1, 1, n, dfn[tp[y]], dfn[y]) + Y; y = f[tp[y]]; } } if (d[x] > d[y]) X = X + rev(gt(1, 1, n, dfn[y], dfn[x])); else Y = gt(1, 1, n, dfn[x], dfn[y]) + Y; return X + Y; } signed main() { freopen("paint1.in","r",stdin); // freopen("yoimiya.out","w",stdout); ios::sync_with_stdio(0); cin >> n >> q; col = n; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } dfs(1); dfs(1, 1); for (int i = 1; i <= n; i++) xc[i] = i, C[i] = i; bd(1, 1, n); // cout<<siz[1]<<endl; // cout<<d[LCA(816,791)]<<endl; // cout<<d[791]<<endl; //return 0; while (q--) { int op; cin >> op; if (op == 1) { int x; cin >> x; mod(x, ++col); } else if (op == 2) { int x, y; cin >> x >> y; cout << gt(x, y).cnt << endl; } else { int x; cin >> x; cout << gt(1, 1, n, dfn[x], dfn[x] + siz[x] - 1).mx << endl; } } cout.flush(); return 0; } /* 5 2 1 2 2 3 3 4 3 5 1 4 3 3 */ ```
by Ranger_HoFr @ 2024-02-25 17:18:59


|