题目描述

给出一棵边带权的节点数量为n的树,初始树上所有节点都是白色。有两种操作:

C x,改变节点x的颜色,即白变黑,黑变白

A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为0)。

N (N <= 100000) Q <= 200000

时限1s

题解

如果没有修改的话,直接点分治,记录子树最深的白点即可。

但是有修改。

发现,点分治的递归层数是O(logn)的

而且这个递归的联通块的根形成一个树形结构。不妨叫点分树。

我们的答案是在所有递归出来的块里ans取max

发现,每次改变一个点的颜色,会影响自己的联通块,以及点分树上这个点的所有father的答案。

树高logn

所以,我们考虑暴力修改每一层的答案。

用三个堆来维护。

一个堆h0,维护这个点P所代表的点分树的联通块中所有点到点分树上P的father的距离(树上实际距离)。

(好处是,修改的时候,直接自底向上,父亲只要一个,这样不需要在上层再考虑哪个子树变了)

另一个堆h1,维护这个点P的所有儿子的堆顶的值。

我们从一个点P的h1堆里面,找到最大的和次大的,做和就是这一层的最大答案。

如果P是白点,那么答案可以只要最大的。而且ans最少是0

第三个堆,维护所有点代表的联通块的ans。最终答案就在这里。

然后,所有的修改,都是删除之后再插入。

堆的删除,用懒惰堆即可。

代码:

(实现细节较多:例如堆的empty判断)

(堆中不用记录答案出自哪里,随便删除一个,剩下那个就是没有删除的。是没有区别的。直接int的堆即可)

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
il void prin(int x){
if(x/) prin(x/);
putchar(x%+'');
}
namespace Miracle{
const int N=+;
const int inf=0x3f3f3f3f;
int n,m;
struct node{
int nxt,to;
int val;
}e[*N];
int hd[N],cnt;
il void add(int x,int y,int z){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
e[cnt].val=z;
hd[x]=cnt;
}
int fa[N];
int sz[N];
int c[N];
priority_queue<int>h[][N],d[][N],hh,dd; int dis[N][];
int dep[N];
int nowsz;
int rt,mxsz[N];
int ans[N];
bool vis[N];
int gen;
il void dfs1(int x,int ff,int d){
dep[x]=d;
sz[x]=;
mxsz[x]=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==ff) continue;
if(vis[y]) continue;
dfs1(y,x,d);
sz[x]+=sz[y];
mxsz[x]=max(mxsz[x],sz[y]);
}
mxsz[x]=max(mxsz[x],nowsz-sz[x]);
if(mxsz[x]<=nowsz/){
rt=x;
}
}
il void dfs2(int x,int ff,int d){
sz[x]=;
if(d!=) h[][rt].push(dis[x][d-]);
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(vis[y]) continue;
if(y==ff) continue;
dis[y][d]=dis[x][d]+e[i].val;
dfs2(y,x,d);
sz[x]+=sz[y];
}
}
il void clear(int x,int k){
if(h[k][x].empty()) return;
while(d[k][x].size()&&h[k][x].size()&&h[k][x].top()==d[k][x].top()){
h[k][x].pop();d[k][x].pop();
}
}
il void upda(int x){
//cout<<" updaing "<<x<<endl;
ans[x]=-inf;
if(c[x]==) ans[x]=max(ans[x],);
clear(x,);
if(!h[][x].empty()){
//cout<<" sz "<<h[1][x].size()<<" "<<d[1][x].size()<<endl;
int tmp=h[][x].top();h[][x].pop();
//cout<<" tmp "<<tmp.id<<" "<<tmp.val<<endl;
if(c[x]==){
ans[x]=max(ans[x],tmp);
}
clear(x,);
if(!h[][x].empty()){
ans[x]=max(ans[x],tmp+(h[][x].top()));
}
h[][x].push(tmp);
}
}
il int divi(int x,int d,int ff){
//cout<<" x d ff "<<x<<" "<<d<<" "<<ff<<endl;
rt=;
dfs1(x,,d);
fa[rt]=ff;
dis[rt][d]=;
dfs2(rt,,d); vis[rt]=;
ans[rt]=-inf;
int now=rt;
for(reg i=hd[now];i;i=e[i].nxt){
int y=e[i].to;
if(vis[y]) continue;
nowsz=sz[y];
int son=divi(y,d+,now); if(h[][son].size()){
h[][now].push(h[][son].top());
}
}
upda(now);
//cout<<" rt "<<now<<" : "<<ans[now]<<endl;
hh.push(ans[now]);
return now;
}
il void wrk(int x){
int gg=x;
int nd=dep[x];
if(c[x]==){
c[x]^=;
while(x){
//cout<<" xx nd "<<x<<" "<<nd<<" "<<endl;
dd.push(ans[x]);
clear(x,);
upda(x);
hh.push(ans[x]); if(fa[x]){
if(h[][x].size()) d[][fa[x]].push(h[][x].top());
d[][x].push(dis[gg][nd-]);
clear(x,);
if(h[][x].size()) h[][fa[x]].push(h[][x].top());
} x=fa[x];
--nd;
}
}
else{
c[x]^=;
while(x){
dd.push(ans[x]);
clear(x,);
upda(x);
hh.push(ans[x]); if(fa[x]){
if(h[][x].size()) d[][fa[x]].push(h[][x].top());
h[][x].push(dis[gg][nd-]);
clear(x,);
if(h[][x].size()) h[][fa[x]].push(h[][x].top());
} x=fa[x];
--nd;
}
}
}
int main(){
scanf("%d",&n);int x,y,z;
for(reg i=;i<=n-;++i){
rd(x);rd(y);rd(z);
add(x,y,z);add(y,x,z);
}
nowsz=n;
gen=divi(,,);
int m;
rd(m);
char ch[];
while(m--){
scanf("%s",ch+);
if(ch[]=='A'){ while(dd.size()&&hh.size()&&hh.top()==dd.top()){
hh.pop();dd.pop();
}
if(!hh.size()){
puts("They have disappeared.");
}
else{
int tmp=hh.top();
if(tmp==-inf) puts("They have disappeared.");
else {
(tmp<)&&(tmp=-tmp,putchar('-'));
prin(tmp);putchar('\n');
}
}
}else{
rd(x);
wrk(x);
}
// cout<<" ans------- "<<endl;
// for(reg i=1;i<=n;++i){
// cout<<i<<" : "<<ans[i]<<endl;
// }
}
return ;
} }
int main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/11/28 9:20:15
*/

你也可以顺带AC[ZJOI2007]捉迷藏

Qtree4——动态点分治的更多相关文章

  1. COJ 0346 WZJ的旅行(二)更新动态树分治版本

    WZJ的旅行(二) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 时隔多日,WZJ又来到了幻想国旅行.幻想国由N个城市组成,由 ...

  2. BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)

    这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...

  3. 【Learning】 动态树分治

    简介 动态树分治整体上由点分治发展而来. 点分治是统计树上路径,而动态树分治用来统计与点有关的树上路径,比如多次询问某一些点到询问点的距离和. 前置知识就是点分治. 做法 众所周知,点分树(点分治中重 ...

  4. 【BZOJ4372】烁烁的游戏(动态点分治)

    [BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...

  5. 【BZOJ3730】震波(动态点分治)

    [BZOJ3730]震波(动态点分治) 题面 BZOJ 题意 给定一棵树, 每次询问到一个点的距离\(<=K\)的点的权值之和 动态修改权值, 强制在线 题解 正常的\(DP\)??? 很简单呀 ...

  6. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

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

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

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

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

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

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

随机推荐

  1. test zhenai

    web.Document.InvokeScript("eval",new string[]{"document.getElementById('passwordbt'). ...

  2. 20155211 网络攻防技术 Exp7 网络欺诈防范

    20155211 网络攻防技术 Exp7 网络欺诈防范 实践内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 (1)简单应用SET工具建立冒名网站 (2)e ...

  3. controlfile 备份到trace文件例子

    主要是为了学习oracle的克隆.参考: http://www.dba-oracle.com/oracle_tips_db_copy.htm 执行: SQL>alter database bac ...

  4. SSIS 包配置

    在商业智能解决方案中,SSIS工程有两种部署模式:工程部署(project deployment)和包部署(package deployment),默认是工程部署模式,在Package的管理上,工程部 ...

  5. phabricator 结合 arcanist 使用

    简介 arcanist 是 phabricator 接口的命令工具,主要用于提交 diff 和 push review 通过的commit. 安装 下载源码,然后指定系统的环境变量即可 $ some_ ...

  6. Unity导入模型出现 (Avatar Rig Configuration mis-match. Bone length in configuration does not match position in animation)?

    昨天遇到这两个模型导入的问题,查了一下资料,自己摸索了一下解决方法..总结一下~ 出现的原因:(问题1)Warning 当模型文件导入以后并且设置Animation Type是Generic的时候,动 ...

  7. WebStorm安装

    用到的链接: WebStorm官网:https://www.jetbrains.com/webstorm 破解补丁与注册码网址:http://idea.lanyus.com/ 有条件的朋友请购买正版. ...

  8. IT简历

    对很多IT毕业生来说,写简历投简历是必不可少的.一个好的简历已是面试成功的一半. 简历的目的是为了引人注意,争取让HR主动联系你去面试,不可避免的在简历中掺杂着一些水分,但是能争取到面试机会,再与HR ...

  9. win2003无线网卡驱动无法安装解决方法

    Windows 2003 Server对无线网卡的pci资源分配出了问题,而笔记本bios中屏蔽了pci配置项,无法修改. 打开资源管理器菜单,工具-文件夹选项-显示,去掉“隐藏受保护的操作系统文件” ...

  10. java 中的内部类总结

    内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类. 如同一个人是由大脑.肢体.器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液.跳动). 显 ...