终于把这个坑填了..

按重心分治建树,每个点存两个堆,第一个存的是这个点子树中的点到父重心的距离,第二个存的是子节点第一个堆的堆顶,同时有一个全局答案堆,存的是每个点第二个堆的最大值+次大值。

20亿个蒟蒻们给了我一份漏洞百出的代码,害的我想了半天..

#include <cstdio>
#include <queue>
using namespace std; const int N=,M=;
char op[];
int n,e,x,y,q,tt,sm,mn,rt,hd[N],nx[M],to[M],v[N],f[N],a[N],d[N],sz[N],g[N][];
struct hep {
priority_queue<int> ad,dl;
void pu(int x) {ad.push(x);}
void po(int x) {dl.push(x);}
int tp() {while(!dl.empty()&&ad.top()==dl.top()) ad.pop(),dl.pop(); return ad.top();}
int gt() {int a=tp(); ad.pop(); int b=tp(); ad.push(a); return a+b;}
}a1,q1[N],q2[N];
void ad(int x,int y) {to[++e]=y,nx[e]=hd[x],hd[x]=e;} void dfs2(int x) {for(int i=hd[x];i;i=nx[i]) if(!d[to[i]]) d[to[i]]=d[x]+,g[to[i]][]=x,dfs2(to[i]);}
int lca(int x,int y) {
if(d[x]<d[y]) swap(x,y);
for(int i=;~i;i--) if(d[g[x][i]]>=d[y]) x=g[x][i];
if(x==y) return x;
for(int i=;~i;i--) if(g[x][i]^g[y][i]) x=g[x][i],y=g[y][i];
return g[x][];
}
int ds(int x,int y) {return d[x]+d[y]-d[lca(x,y)]*;}
void dfs(int x,int fa) {
sz[x]=;
for(int i=hd[x];i;i=nx[i]) if(to[i]!=fa&&!v[to[i]]) dfs(to[i],x),sz[x]+=sz[to[i]];
}
void gt(int x,int fa) {
int mx=; sz[x]=;
for(int i=hd[x];i;i=nx[i]) if(to[i]!=fa&&!v[to[i]]) gt(to[i],x),sz[x]+=sz[to[i]],mx=max(mx,sz[to[i]]);
mx=max(mx,tt-sz[x]);
if(mx<mn) mn=mx,rt=x;
}
void bd(int x,int y) {
gt(x,),f[rt]=y,v[rt]=,dfs(rt,); int k=rt;
for(int i=hd[rt];i;i=nx[i]) if(!v[to[i]]) tt=mn=sz[to[i]],bd(to[i],k);
}
void cal(int x) {
int u=x;
if(q2[x].ad.size()-q2[x].dl.size()>=) a1.po(q2[x].gt());
q2[x].pu();
if(q2[x].ad.size()-q2[x].dl.size()>=) a1.pu(q2[x].gt());
while(f[u]) {
if(q2[f[u]].ad.size()-q2[f[u]].dl.size()>=) a1.po(q2[f[u]].gt());
if(q1[u].ad.size()-q1[u].dl.size()) q2[f[u]].po(q1[u].tp());
q1[u].pu(ds(f[u],x)),q2[f[u]].pu(q1[u].tp());
if(q2[f[u]].ad.size()-q2[f[u]].dl.size()>=) a1.pu(q2[f[u]].gt());
u=f[u];
}
}
void cal2(int x) {
int u=x;
if(q2[x].ad.size()-q2[x].dl.size()>=) a1.po(q2[x].gt());
q2[x].po();
if(q2[x].ad.size()-q2[x].dl.size()>=) a1.pu(q2[x].gt());
while(f[u]) {
if(q2[f[u]].ad.size()-q2[f[u]].dl.size()>=) a1.po(q2[f[u]].gt());
q2[f[u]].po(q1[u].tp()),q1[u].po(ds(f[u],x));
if(q1[u].ad.size()-q1[u].dl.size()) q2[f[u]].pu(q1[u].tp());
if(q2[f[u]].ad.size()-q2[f[u]].dl.size()>=) a1.pu(q2[f[u]].gt());
u=f[u];
}
} int main() {
scanf("%d",&n),sm=n;
for(int i=;i<n;i++) scanf("%d%d",&x,&y),ad(x,y),ad(y,x);
tt=mn=n,bd(,),d[]=,dfs2();
for(int j=;j<;j++)
for(int i=;i<=n;i++)
g[i][j]=g[g[i][j-]][j-];
for(int i=;i<=n;i++) cal(i);
scanf("%d",&q);
while(q--) {
scanf("%s",op);
if(op[]=='G') {
if(sm<=) printf("%d\n",sm-);
else printf("%d\n",a1.tp());
}
else {
scanf("%d",&x),a[x]^=;
if(a[x]) sm--,cal2(x); else sm++,cal(x);
}
}
return ;
}

BZOJ1095(动态点分治+堆)的更多相关文章

  1. 【bzoj1095】[ZJOI2007]Hide 捉迷藏 动态点分治+堆

    题目描述 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这 ...

  2. BZOJ_1095_[ZJOI2007]Hide 捉迷藏_动态点分治+堆

    BZOJ_1095_[ZJOI2007]Hide 捉迷藏_动态点分治+堆 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子 ...

  3. BZOJ1095 [ZJOI2007]Hide 捉迷藏 动态点分治 堆

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ1095.html 题目传送门 - BZOJ1095 题意 有 N 个点,每一个点是黑色或者白色,一开始所 ...

  4. BZOJ1095 [ZJOI2007]Hide 捉迷藏 【动态点分治 + 堆】

    题目链接 BZOJ1095 题解 传说中的动态点分治,一直不敢碰 今日一会,感觉其实并不艰涩难懂 考虑没有修改,如果不用树形dp的话,就得点分治 对于每个重心,我们会考虑其分治的子树内所有点到它的距离 ...

  5. 【BZOJ1095】[ZJOI2007]Hide 捉迷藏 动态树分治+堆

    [BZOJ1095][ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉 ...

  6. bzoj 1095 Hide 捉迷藏 - 动态点分治 -堆

    Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双 ...

  7. BZOJ 1095: [ZJOI2007]Hide 捉迷藏 动态点分治+堆

    写了7k多,可以说是一己之力切掉了这道毒瘤题~ 开 $3$ 种堆,分别维护每个子树最大深度,以及每个节点在点分树中对父亲的贡献,和全局的最优解. 由于需要支持堆的删除,所以写起来特别恶心+麻烦. 细节 ...

  8. 【BZOJ1095】捉迷藏(动态点分治)

    [BZOJ1095]捉迷藏(动态点分治) 题面 BZOJ 题解 动态点分治板子题 假设,不考虑动态点分治 我们来想怎么打暴力: \(O(n)DP\)求树的最长链 一定都会.不想解释了 所以,利用上面的 ...

  9. 动态点分治:Bzoj1095: [ZJOI2007]Hide 捉迷藏

    简介 这是我自己的一点理解,可能写的不好 点分治都学过吧.. 点分治每次找重心把树重新按重心的深度重建成了一棵新的树,称为分治树 这个树最多有log层... 动态点分治:记录下每个重心的上一层重心,这 ...

随机推荐

  1. Tomcat 8项目无法启动,无报错

    作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs Tomcat 8启动很慢,且日志上无任何错误,在日志中查看到如下信息: Log4j:[2015-10-29 ...

  2. thinkphp调试技巧

    调试的经验:很多时候程序调试不出来,但是又找不出错误,往往是拼写错误可能是很小的拼写错误,很难看出,或者多了一个空格,比如在配置路由的时候'URL_ROUTER_ON '=true,这样设置就会错误, ...

  3. C语言学习(二)

    今天在程序员面试题中,碰到一个有意思的题目:数组a[N],存放了1至N-1个数,其中某个数重复一次,现在要求找出重复的数字且程序时间复杂度必须为O(N).乍一看,如果不计时间复杂度和空间复杂度程序比较 ...

  4. sts 和 lombok

    1.安装lombok.jar到sts.exe所在目录 如果是eclipse,需要放到eclipse.exe所在目录,同理myeclipse. 2.修改sts.ini配置使用lombok 如果是ecli ...

  5. css3中的动画 @keyframes animation

    动画的运用比较重要.接下来我希望针对我自己学习遇到的问题,再总结一下这个属性的使用方法. 创建一个动画: @keyframes 动画名 {样式} 引用自己创建的动画: animation:动画名  时 ...

  6. tornado框架源码分析---Application类之debug参数

    先贴上Application这个类的源码. class Application(httputil.HTTPServerConnectionDelegate): """A ...

  7. EOJ3536 求蛇形矩阵每一行的和---找规律

    题目链接: https://acm.ecnu.edu.cn/problem/3536/ 题目大意: 求蛇形矩阵的每一行的和,数据范围n<=200000. 思路: 由于n数据较大,所以感觉应该是需 ...

  8. 小技巧-WEB API第一次加载很慢

    原文:http://www.afuhao.com/article_articleId-219.shtml 摘要:ASP.NET页面首次打开很慢,但别的页面如果没有访问过,去访问也会慢.你也许认为它是在 ...

  9. Linux(一)VMware虚拟机的安装

    vmware的安装文件: 链接:https://pan.baidu.com/s/1QGjNqRZzE-vV7Af0PI2QYA 密码:omfe 1.1 首先下载安装包 安装包的内容 1.2 双击exe ...

  10. Mybatis JPA 插件简介(v2.1.0)

    相比之前的版本(v1.1.0),此版本(v2.1.0)做了较大的改动. 项目地址: github https://github.com/cnsvili/mybatis-jpa gitee https: ...