https://www.lydsy.com/JudgeOnline/problem.php?id=1095

动态点分治

其实就是做点分治时把当前找出来的重心向上一次找到的重心连边,

这样可以是重构后的树高为log的。

重构后的数称为点分树。

构造出点分树,

每个节点开两个堆分别维护子树到它的所有链和他的子树到父分治节点的所有链。

再开一个全局堆维护每个节点的最大答案。

老年选手表示已经码不动数据结构,debug 2hours,QWQ。

#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#define re register
#define rep(i,s,t) for(register int i=s;i<=t;++i)
#define _rep(i,s,t) for(register int i=s;i>=t;--i)
#define Rep(i,s,t) for(register int i=s;i<t;++i)
#define go(x) for(register int e=las[x];e;e=nxt[e])
using namespace std;
namespace IO{#define gc getchar()#define pc(x) putchar(x)template<typename T>inline void read(T &x){x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;}while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return;}template<typename T>inline void write(T x=0){T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48);while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return;}
}
using IO::read;
using IO::write;
#define gi(x) read(x)
#define gii(x,y) read(x),read(y)
#define giii(x,y,z) read(x),read(y),read(z)
const int N=2e5+11,inf=1<<30;
int n,m,tot,x,y,sum,rt;
int nxt[N],las[N],to[N],up[N][18],dep[N];
int sz[N],mx[N],fa[N];
bool vis[N],light[N];
struct heap{priority_queue<int>A,B;inline void push(int x){A.push(x);}inline void erase(int x){B.push(x);}inline int top(){for(;B.size()&&A.top()==B.top();)A.pop(),B.pop();if(A.size())return A.top();return 0;}inline void pop(){for(;B.size()&&A.top()==B.top();)A.pop(),B.pop();if(A.size())A.pop();}inline int sec(){re int tmp=top();pop();re int ret=top();push(tmp);return ret;}inline int size(){return A.size()-B.size();}
}c[N>>1],f[N>>1],ans;
inline void ins(heap &s){//if(s.size()>1)//    printf("ins:%d %d\n",s.top(),s.sec());if(s.size()>1)ans.push(s.top()+s.sec());
}
inline void del(heap &s){//if(s.size()>1)//    printf("del:%d %d\n",s.top(),s.sec());if(s.size()>1)ans.erase(s.top()+s.sec());
}
inline void add(int x,int y){nxt[++tot]=las[x],las[x]=tot,to[tot]=y;
}
inline void dfs(int x,int anc){up[x][0]=anc;rep(i,1,17)up[x][i]=up[up[x][i-1]][i-1];go(x){if(to[e]==anc)continue;dep[to[e]]=dep[x]+1;dfs(to[e],x);}
}
inline int lca(int x,int y){if(dep[x]<dep[y])swap(x,y);int t=dep[x]-dep[y];_rep(i,17,0)if(t>>i&1)x=up[x][i];if(x==y)return x;_rep(i,17,0)if(up[x][i]!=up[y][i])x=up[x][i],y=up[y][i];return up[x][0];
}
inline int dis(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];
}
inline void findrt(int x,int anc){sz[x]=1,mx[x]=0;go(x){if(vis[to[e]]||to[e]==anc)continue;findrt(to[e],x);sz[x]+=sz[to[e]];mx[x]=max(mx[x],sz[to[e]]);}mx[x]=max(mx[x],sum-sz[x]);if(mx[x]<mx[rt])rt=x;
}
inline void work(int x,int anc,int R){//printf("%d %d %d\n",x,anc,R);
    f[rt].push(dis(x,R));go(x){if(to[e]==anc||vis[to[e]])continue;work(to[e],x,R);}
}
inline void build_tree(int x,int anc){fa[x]=anc,vis[x]=1,c[x].push(0),work(x,0,anc);//printf("%d %d\n",x,anc);int v;go(x){if(vis[to[e]])continue;rt=0,mx[0]=inf,sum=sz[to[e]],findrt(to[e],x),v=rt,build_tree(rt,x);c[x].push(f[v].top());}ins(c[x]);
}
inline void on(int x){del(c[x]),c[x].erase(0),ins(c[x]);for(re int i=x;i;i=fa[i]){del(c[fa[i]]);if(f[i].size())c[fa[i]].erase(f[i].top());f[i].erase(dis(x,fa[i]));if(f[i].size())c[fa[i]].push(f[i].top());ins(c[fa[i]]);}
}
inline void off(int x){del(c[x]),c[x].push(0),ins(c[x]);for(re int i=x;i;i=fa[i]){del(c[fa[i]]);if(f[i].size())c[fa[i]].erase(f[i].top());f[i].push(dis(x,fa[i]));if(f[i].size())c[fa[i]].push(f[i].top());ins(c[fa[i]]);}
}
int main(){gi(n);rep(i,2,n){gii(x,y);add(x,y),add(y,x);}dfs(1,0),mx[0]=inf,rt=0,sum=n,findrt(1,0),build_tree(rt,0);int num=n,q;char ch[10];gi(q);for(;q--;){scanf("%s",ch);if(ch[0]=='C'){gi(x);if(light[x])off(x),++num;elseon(x),--num;light[x]^=1;}elseprintf("%d\n",num<=1?num-1:ans.top());}return 0;
}

code

转载于:https://www.cnblogs.com/Stump/p/9218105.html

BZOJ1095 动态点分治相关推荐

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

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

  2. bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习

    好迷啊...感觉动态点分治就是个玄学,蜜汁把树的深度缩到logn (静态)点分治大概是递归的时候分类讨论: 1.答案经过当前点,暴力(雾)算 2.答案不经过当前点,继续递归 由于原树可以长的奇形怪状( ...

  3. 【BZOJ1095】捉迷藏,动态点分治

    传送门 题意 给定一棵树,树上的点是黑点或白点,修改一个点的颜色或查询树上两个最远黑点的距离 原本以为动态点分治是个什么很高级的东西 原来不是像LCT一样恶心的东西啊,但也很恶心了 问了问别人才知道所 ...

  4. BZOJ1095 [ZJOI2007]捉迷藏 动态点分治

    每次修改一个点的黑白状态,询问树上最远黑点距离 拿这个题做动态点分治模板题:(%%%PoPoQQQ大爷) 点分治的过程是对树块找重心之后分成多个小树块,降低规模分别处理的过程,把链的信息收到其中&qu ...

  5. 点分治动态点分治小结

    (写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...

  6. 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治

    题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...

  7. [Codeforces757G]Can Bash Save the Day?——动态点分治(可持久化点分树)

    题目链接: Codeforces757G 题目大意:给出一棵n个点的树及一个1~n的排列pi,边有边权,有q次操作: 1 l r x 求 $\sum\limits_{i=l}^{r}dis(p_{i} ...

  8. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作: Q x:询问x的点权. M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m 接下来的 ...

  9. BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

最新文章

  1. Python中yield和yield from的用法
  2. 【深度学习理论】(2) 卷积神经网络
  3. 一文盘点三大顶级Python库(附代码)
  4. Gerrit 代码审核服务器的工作流和原理
  5. 【Matlab 控制】利用 Simulink 对微分代数方程建模
  6. cookies共享 sso_cookie共享(单点登录)
  7. Core Dump流程分析
  8. Spring入门介绍:
  9. python多进程加快for循环_python多进程 通过for循环 join 的问题
  10. chrome启用flash_如何在Google Chrome中启用Adobe Flash Player
  11. 第二十二期:动画讲解TCP,再不懂请来打我
  12. 通过www服务器提供的起始网页就能访问,2010春2题目.doc
  13. 操作系统实验一:父子进程通信
  14. 匹兹堡大学胡京通老师招收2023博士生
  15. jzoj3457. 【NOIP2013模拟联考3】沙耶的玩偶
  16. 【Excel】一、Excel入门指导
  17. 考研不歧视双非的院校计算机专业,21考研,保护一志愿不歧视“双非”的30所学校,值得收藏!...
  18. 图像处理中的forward warping 和 inverse warping
  19. 进入计算机专业学习的一些体会和思考以及今后的学习规划
  20. 弹性文件服务(Scalable File Service,SFS)

热门文章

  1. ubuntu 编译android .img_全网可用交叉编译工具链大全
  2. 达奇机器人怎么看电量_圣诞怎么过?看看电影吃点儿特别的
  3. 安装mysql5.7,如何将之前mysql的数据库导入
  4. 一秒钟世界上会发生多少事_一秒之中会发生什么
  5. TMS320C55x的指令系统
  6. 2d游戏引擎_Cocos Creator:用 2D 物理碰撞撸 3D 横版酷跑
  7. php post 漏洞_WordPress漏洞分析
  8. C语言——指针篇(二)指针和数组之内存分配和初始化
  9. ORACLE数据库测试题(一)
  10. 服务器关机显示正在停止服务,云服务器一直停止中