bzoj1095: [ZJOI2007]Hide 捉迷藏
2018-07-01 09:02
399 查看
题目链接
bzoj1095: [ZJOI2007]Hide 捉迷藏题解
建出点分树,每次修改一个结点只影响它到树根的一条链暴力修改实现的时候用三层带修改堆来维护
B.维护每个重心存所有子树到其点分树父亲节点de距离
C.维护子树中的点到根的距离 ,我们可以用子节点的B来更新它
A.全局一个堆,维护答案最大值,就是最长链+次长连
每次修改向上改就行,因为树高时log的复杂度
\(O(nlogn +qlog^2n)\)
rmq lca卡卡常,本题有更优做法..以后再说吧
代码
/* 每次修改一个结点只影响它到树根的一条链 这题具体实现的时候要维护三层堆 B.维护每个重心存所有子树到其点分树父亲节点de距离 C.维护子树中的点到根的距离 ,我们可以用子节点的B来更新它 A.全局一个堆,维护答案最大值, */ #include<queue> #include<cstdio> #include<algorithm> inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); return x; } #define INF 998244353 const int maxn = 300007; int son[maxn],f[maxn],mn[maxn << 1][25],root,tot; struct node { int u,v,next; } edge[maxn << 1]; int head[maxn],num = 0; void add_edge(int u,int v) { edge[++ num].v = v;edge[num].next = head[u];head[u] = num; } int n; int lg[maxn << 1],dfn;// = 0; bool col[maxn]; struct Heap { std::priority_queue<int>A,B; void push(int x) { A.push(x); } void erase(int x) { B.push(x); } void pop() { while(B.size() && A.top() == B.top()) A.pop(),B.pop(); A.pop(); } int top() { while(B.size() && A.top() == B.top()) A.pop(),B.pop(); return A.top(); } int size() { return A.size() - B.size(); } int retop() { if(size() < 2) return 0;int x = top();pop();int ret = top();push(x);return ret;} } b[maxn],c[maxn],ans; void insert(Heap &s) {if(s.size() > 1)ans.push(s.top() + s.retop());} void dele(Heap &s) {if(s.size() > 1) ans.erase(s.top() + s.retop());} int pos[maxn],deep[maxn]; void dfs_rmq (int x,int fa) { mn[pos[x] = ++ dfn][0] = deep[x] ; for(int i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(v == fa)continue; deep[v] = deep[x] + 1; dfs_rmq(v,x); mn[++ dfn][0] = deep[x]; //访问完子树后加上Qwq- } } int lca(int x,int y) { x = pos[x];y = pos[y]; if(y < x) std::swap(x,y); int k = lg[y - x + 1]; return std::min(mn[x][k],mn[y - (1 << k) + 1][k]); } inline int dis(int x,int y) { return deep[x] + deep[y] - 2 * lca(x,y); } bool vis[maxn];int fa[maxn]; void get_root(int x,int fa) { son[x] = 1; f[x] = 0; for(int i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(v == fa || vis[v]) continue; get_root(v,x); son[x] += son[v];f[x] = std::max(f[x],son[v]); } f[x] = std::max(f[x],tot - son[x]); if(f[x] < f[root]) root = x; } void get(int x,int Fa,int rt) { b[root].push(dis(x,fa[root])); for(int i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(v == Fa || vis[v]) continue; get(v,x,rt); } } void build(int x,int Fa) { fa[x] = Fa;vis[x] = 1; c[x].push(0); get(x,0,Fa); for(int i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(!vis[v] && v != Fa) { tot = son[edge[i].v];root = 0;f[0] = INF; get_root(edge[i].v,x); v = root; build(root,x); c[x].push(b[v].top()); } } insert(c[x]); } void turn(int x,bool type) { dele(c[x]); if(type) c[x].erase(0); else c[x].push(0); insert(c[x]); for(int i = x;i;i = fa[i]) { dele(c[fa[i]]); //printf("%d ",i); if(b[i].size()) c[fa[i]].erase(b[i].top()); if(type)b[i].erase(dis(x,fa[i])); else b[i].push(dis(x,fa[i])); if(b[i].size()) c[fa[i]].push(b[i].top()); insert(c[fa[i]]); } //puts(""); } int main() { n = read(); for(int u,v,i = 1;i < n;++ i) { u = read(),v = read(); add_edge(u,v);add_edge(v,u); } dfs_rmq(1,0); for(int i = 2;i <= dfn;++ i) lg[i] = lg[i >> 1] + 1; for(int i = 1;i <= lg[dfn];++ i) for(int j = dfn - (1 << i - 1);j;-- j) mn[j][i] = std::min(mn[j][i - 1],mn[j + (1 << i - 1)][i - 1]); f[0] = INF; root = 0; tot = n; get_root(1,0); build(root,0); char opt[10]; int Q = read(); int sum = n; for(;Q --;) { scanf("%s",opt + 1); if(opt[1] == 'C') { int asd = read(); if(col[asd]) {turn(asd,0); sum ++;col[asd] = 0;} else {turn(asd,1);sum --;col[asd] = 1;} } else { if(sum == 1)puts("0"); else if(!sum)puts("-1"); else printf("%d\n",ans.top()); } } return 0; }
相关文章推荐
- [动态点分治] BZOJ1095: [ZJOI2007]Hide 捉迷藏
- BZOJ1095: [ZJOI2007]Hide 捉迷藏
- BZOJ 1095 [ZJOI2007]Hide 捉迷藏
- 【BZOJ1095】【ZJOI2007】Hide 捉迷藏 线段树维护括号序列 数据结构的压缩。
- [bzoj1095] [ZJOI2007]Hide 捉迷藏
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
- BZOJ1095 [ZJOI2007]Hide 捉迷藏
- 【BZOJ1095】[ZJOI2007]Hide 捉迷藏【动态树分治】
- bzoj1095: [ZJOI2007]Hide 捉迷藏(动态点分治+树上ST表)
- BZOJ1095: [ZJOI2007]Hide 捉迷藏
- 【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏
- BZOJ 1095【ZJOI2007】Hide捉迷藏
- BZOJ1095: [ZJOI2007]Hide 捉迷藏
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏 动态树分治
- [bzoj1095][ZJOI2007]Hide 捉迷藏(动态点分治)
- [BZOJ1095][ZJOI2007][线段树]Hide捉迷藏
- BZOJ_1095_[ZJOI2007]Hide 捉迷藏_动态点分治+堆
- [bzoj1095][ZJOI2007]Hide 捉迷藏——线段树+括号序列
- bzoj 1095: [ZJOI2007]Hide 捉迷藏 (动态点分治)