Solution - P2056 [ZJOI2007] 捉迷藏
我实在是唐到了一个程度……对着一个 4.5k 的代码调了 15h 才调出来
思路
就是一个点分树。
众所周知,点分树需要维护两个数据结构来存对自身和对父亲的贡献,而在这道题里,这个数据结构是一只可删堆。
于是对于修改向上维护就行了。
代码
#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 100005
using namespace std;
int to[N<<1], nxt[N<<1], head[N], gsiz = 1;
#define mkarc(u,v) (++gsiz, to[gsiz]=v, nxt[gsiz]=head[u], head[u]=gsiz)
int fa2[N], dep2[N], dis[N][20], vis[N];
int siz[N], col[N], cnt;
int n, q;
struct Heap{
priority_queue<int> A, B;
inline void insert(rint x){A.push(x); return;}
inline void erase (rint x){B.push(x); return;}
inline int size(){return A.size()-B.size();}
inline void pop(){
while(!B.empty() && A.top() == B.top()) A.pop(), B.pop();
if(!A.empty()) A.pop();
return;
}
inline int top(){
while(!B.empty() && A.top() == B.top()) A.pop(), B.pop();
if(A.empty()) return 0;
return A.top();
}
inline int sec(){
rint tmp = top(); pop();
rint res = top();
insert(tmp);
return res;
}
} sub[N], all[N], ans;
namespace lca{
int dep[N], fa[N][21];
inline void init(rint u = 1, rint _fa = 0){
for(rint i = 1; i < 20; ++i)
fa[u][i] = fa[fa[u][i-1]][i-1];
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i];
if(v == _fa) continue;
dep[v] = dep[u]+1, fa[v][0] = u;
init(v, u);
}
return;
}
inline int lca(rint u, rint v){
if(dep[u] > dep[v]) swap(u, v);
for(rint i = 20; i >= 0; --i)
if(dep[fa[v][i]] >= dep[u]) v = fa[v][i];
if(u == v) return u;
for(rint i = 20; i >= 0; --i)
if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
inline int dis(rint u, rint v){
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
}
inline void dfs1(rint u, rint fa, rint sum, rint& minn, rint& g){
rint mink = 0;
siz[u] = 1;
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i];
if(v == fa || vis[v]) continue;
dfs1(v, u, sum, minn, g);
siz[u] += siz[v], mink = max(mink, siz[v]);
}
mink = max(mink, sum-siz[u]);
if(minn > mink) g = u, minn = mink;
return;
}
inline int dfs2(rint u, rint fa, rint dep, Heap& h){
rint maxn = dep; h.insert(dep);
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i];
if(v == fa || vis[v]) continue;
maxn = max(maxn, dfs2(v, u, dep+1, h));
}
return maxn;
}
inline void prework(rint u){
vis[u] = true, sub[u].insert(0);
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i], sum = siz[v], minn = 1e9+7;
if(vis[v]) continue;
dfs1(v, 0, sum, minn, v);
dfs1(v, 0, sum, minn, v);
fa2[v] = u, dep2[v] = dep2[u]+1;
sub[u].insert(dfs2(to[i], u, 1, all[v]));
prework(v);
}
if(sub[u].size() >= 2) ans.insert(sub[u].top()+sub[u].sec());
else ans.insert(sub[u].top());
return;
}
#define getdis(u,v) (dis[u][dep2[u]-dep2[v]])
int main(){
scanf("%d", &n);
for(rint i = 1; i < n; ++i){
rint u, v, w;
scanf("%d %d", &u, &v);
mkarc(u, v), mkarc(v, u);
}
siz[1] = cnt = n;
lca::init();
rint minn = 1e9+7, g;
dfs1(1, 0, n, minn, g);
dfs1(g, 0, n, minn, g);
dep2[g] = 1;
prework(g);
for(rint i = 1; i <= n; ++i)
for(rint j = i; j; j = fa2[j])
dis[i][dep2[i]-dep2[j]] = lca::dis(i, j);
scanf("%d", &q);
while(q--){
char op[2];
scanf("%s", op);
if(op[0] == 'G'){
if(cnt == 0)
puts("-1");
else
printf("%d\n", ans.top());
}
else{
rint x = 0;
scanf("%d", &x);
if(col[x] == 0){
if(sub[x].size() >= 2) ans.erase(sub[x].top()+sub[x].sec());
sub[x].erase(0);
if(sub[x].size() >= 2) ans.insert(sub[x].top()+sub[x].sec());
for(rint i = x; fa2[i]; i = fa2[i]){
if(sub[fa2[i]].size() >= 2) ans.erase(sub[fa2[i]].top()+sub[fa2[i]].sec());
if(all[i].size()) sub[fa2[i]].erase(all[i].top());
all[i].erase(getdis(x, fa2[i]));
if(all[i].size()) sub[fa2[i]].insert(all[i].top());
if(sub[fa2[i]].size() >= 2) ans.insert(sub[fa2[i]].top()+sub[fa2[i]].sec());
}
--cnt;
}
else{
if(sub[x].size() >= 2) ans.erase(sub[x].top()+sub[x].sec());
sub[x].insert(0);
if(sub[x].size() >= 2) ans.insert(sub[x].top()+sub[x].sec());
for(rint i = x; fa2[i]; i = fa2[i]){
if(sub[fa2[i]].size() >= 2) ans.erase(sub[fa2[i]].top()+sub[fa2[i]].sec());
if(all[i].size()) sub[fa2[i]].erase(all[i].top());
all[i].insert(getdis(x, fa2[i]));
if(all[i].size()) sub[fa2[i]].insert(all[i].top());
if(sub[fa2[i]].size() >= 2) ans.insert(sub[fa2[i]].top()+sub[fa2[i]].sec());
}
++cnt;
}
col[x] ^= 1;
}
}
return 0;
}

浙公网安备 33010602011771号