luoguP4115 QTREE4 链分治
Posted reverymoon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP4115 QTREE4 链分治相关的知识,希望对你有一定的参考价值。
具体看$qzc$论文吧......陈年老物了......
主要注意每个链头一棵线段树而不是一棵全局线段树
修改操作写完就是正确的,反而是初始化调了好一会......
跑的还是很快的,有些地方没优化常数也还可以接受
在$luogu$上把$Toptree$给卡下去了,现居$rank1$......
代码的话....借鉴一下思想就行了
实现就没有必要有些地方做得一样了
#include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; extern inline char gc() { static char RR[23456], *S = RR + 23333, *T = RR + 23333; if(S == T) fread(RR, 1, 23333, stdin), S = RR; return *S ++; } inline int read() { int p = 0, w = 1; char c = gc(); while(c > ‘9‘ || c < ‘0‘) { if(c == ‘-‘) w = -1; c = gc(); } while(c >= ‘0‘ && c <= ‘9‘) p = p * 10 + c - ‘0‘, c = gc(); return p * w; } #define sid 100050 #define eid 200050 #define ri register int const int inf = 1e9; struct heap { priority_queue <int> f, g; inline void ins(int v) { if(v != -inf) f.push(v); } inline void era(int v) { if(v != -inf) g.push(v); } inline int top() { while(1) { if(f.empty()) return -inf; if(g.empty()) return f.top(); if(f.top() == g.top()) f.pop(), g.pop(); else return f.top(); } } } h[sid], ans; int n, m, wn, cnp; int cap[sid], nxt[eid], node[eid], fee[eid]; inline void addeg(int u, int v, int w) { nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v; fee[cnp] = w; nxt[++ cnp] = cap[v]; cap[v] = cnp; node[cnp] = u; fee[cnp] = w; } #define cur node[i] int sz[sid], pre[sid], fa[sid], dep[sid]; inline void dfs(int o) { sz[o] = 1; for(int i = cap[o]; i; i = nxt[i]) if(cur != fa[o]) { fa[cur] = o; dep[cur] = dep[o] + fee[i]; dfs(cur); sz[o] += sz[cur]; if(sz[cur] > sz[pre[o]]) pre[o] = cur; } } int id, onp, col[sid]; int anc[sid], len[sid], dfn[sid], ord[sid]; inline void dfs(int o, int tp) { dfn[o] = ++ id; anc[o] = tp; ord[id] = o; len[tp] ++; if(!pre[o]) return; dfs(pre[o], tp); for(int i = cap[o]; i; i = nxt[i]) if(cur != fa[o] && cur != pre[o]) dfs(cur, cur); } int tnp, rt[sid]; struct seg { int l, r, v, ls, rs; } t[sid * 4]; #define dis(x) dep[ord[x]] inline void upd(int o, int l, int r) { int ls = t[o].ls, rs = t[o].rs, mid = (l + r) >> 1; t[o].l = max(t[ls].l, t[rs].l + dis(mid + 1) - dis(l)); t[o].r = max(t[rs].r, t[ls].r + dis(r) - dis(mid)); t[o].v = max(max(t[ls].v, t[rs].v), t[ls].r + t[rs].l + dis(mid + 1) - dis(mid)); } inline void build(int &o, int l, int r) { if(!o) o = ++ onp; if(l == r) { int x = ord[l]; for(ri i = cap[x]; i; i = nxt[i]) if(cur != fa[x] && cur != pre[x]) h[x].ins(t[rt[cur]].l + dep[cur] - dep[x]); int d1 = h[x].top(); h[x].era(d1); int d2 = h[x].top(); h[x].ins(d1); t[o].l = t[o].r = max(d1, 0); t[o].v = max(0, max(d1, d1 + d2)); return; } int mid = (l + r) >> 1; build(t[o].ls, l, mid); build(t[o].rs, mid + 1, r); upd(o, l, r); } inline void mdf(int o, int l, int r, int v, int s) { if(l == r) { if(v == s) { int d1 = h[v].top(); h[v].era(d1); int d2 = h[v].top(); h[v].ins(d1); if(col[v]) t[o].l = t[o].r = d1, t[o].v = d1 + d2; else t[o].l = t[o].r = max(d1, 0), t[o].v = max(0, max(d1, d1 + d2)); } else { h[v].ins(t[rt[s]].l + dep[s] - dep[v]); int d1 = h[v].top(); h[v].era(d1); int d2 = h[v].top(); h[v].ins(d1); if(col[v]) t[o].l = t[o].r = d1, t[o].v = d1 + d2; else t[o].l = t[o].r = max(d1, 0), t[o].v = max(0, max(d1, d1 + d2)); } return; } int mid = (l + r) >> 1; if(dfn[v] <= mid) mdf(t[o].ls, l, mid, v, s); else mdf(t[o].rs, mid + 1, r, v, s); upd(o, l, r); } int main() { wn = n = read(); for(ri i = 1; i < n; i ++) { int u = read(), v = read(); int w = read(); addeg(u, v, w); } dfs(1); dfs(1, 1); ans.ins(0); for(ri i = n; i; i --) { int o = ord[i]; if(o != anc[o]) continue; build(rt[o], dfn[o], dfn[o] + len[o] - 1); ans.ins(t[rt[o]].v); } m = read(); char opt = 0; for(ri i = 1; i <= m; i ++) { opt = gc(); while(opt != ‘C‘ && opt != ‘A‘) opt = gc(); if(opt == ‘C‘) { int x = read(); col[x] ^= 1; if(col[x] == 0) wn ++; else wn --; for(ri o = x, p = o; o; o = fa[o]) { int f = anc[o]; int p1 = t[rt[f]].v, d1 = t[rt[f]].l; if(fa[f]) h[fa[f]].era(t[rt[f]].l + dep[f] - dep[fa[f]]); mdf(rt[f], dfn[f], dfn[f] + len[f] - 1, o, p); int p2 = t[rt[f]].v, d2 = t[rt[f]].l; if(p1 != p2) ans.era(p1), ans.ins(p2); p = o = f; } } else { if(wn == 0) printf("They have disappeared. "); else printf("%d ", ans.top()); } } return 0; }
以上是关于luoguP4115 QTREE4 链分治的主要内容,如果未能解决你的问题,请参考以下文章