【bzoj 1095】[ZJOI2007]Hide 捉迷藏
题目链接:
题解:
样例好良心,调样例3h一A……
细节好多……诸如没完没了的pop和push……搞得头都大了。
同情zzh……调了整一天了。
动态点分治裸题……果然每个“裸题”打起来都跟shi一样。
题目:
#define Troy
#define inf 0x7fffffff #include <bits/stdc++.h> using namespace std; inline int read(){
int s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return k*s;
} const int N=1e5+; struct edges{
int v;edges *last;
}edge[N<<],*head[N];int cnt; inline void push(int u,int v){
edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
} int n,m,f[N][],deep[N],bit[]; inline void dfs(int x){
for(int i=;bit[i]<=deep[x];++i)
f[x][i]=f[f[x][i-]][i-];
for(edges *i=head[x];i;i=i->last) if(i->v!=f[x][]){
deep[i->v]=deep[x]+;
f[i->v][]=x;
dfs(i->v);
}
} inline int lca(int x,int y){
int ret=deep[x]+deep[y];
if(deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for(int i=;t;++i)
if(bit[i]&t) t^=bit[i],x=f[x][i];
if(x!=y){
for(int i=;~i;--i)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
x=f[x][];
}
return ret-(deep[x]<<);
} priority_queue<int,vector<int>,less<int> > q[N][],e[N][],ans,anse;
int size[N],heavy[N],top,tot,root,lastans[N],lasttop[N],fat[N];
bool vis[N]; inline void dfs(int x,int fa){
size[x]=;
heavy[x]=;
for(edges *i=head[x];i;i=i->last) if(!vis[i->v]&&i->v!=fa){
dfs(i->v,x);
size[x]+=size[i->v];
heavy[x]=max(heavy[x],size[i->v]);
}heavy[x]=max(heavy[x],tot-size[x]);
if(heavy[x]<top) top=heavy[x],root=x;
} inline void build(int x,int fa,int grand){
q[grand][].push(lca(x,fat[grand]));
size[x]=;
for(edges *i=head[x];i;i=i->last) if(!vis[i->v]&&i->v!=fa)
build(i->v,x,grand),size[x]+=size[i->v];
} inline void build(int x,int fa){
top=inf;
dfs(x,x);
vis[x=root]=true;
dfs(x,x);
fat[x]=fa;
build(x,x,x);
for(edges *i=head[x];i;i=i->last)if(vis[i->v]^){
tot=size[i->v];
build(i->v,x);
if(q[root][].empty()^)
q[x][].push(lasttop[root]=q[root][].top());
}
if(!q[x][].empty()){
int a1=q[x][].top();
q[x][].pop();
ans.push(lastans[x]=a1+(q[x][].empty()?:q[x][].top()));
q[x][].push(a1);
}
root=x;
} inline void putans(){
while(!ans.empty()&&!anse.empty()){
if(ans.top()==anse.top())
ans.pop(),anse.pop();
else break;
}
if(tot<=){
printf("%d\n",tot-);
}else
printf("%d\n",ans.top());
} inline void clear(int x,bool k){
while(!q[x][k].empty()&&!e[x][k].empty()&&q[x][k].top()==e[x][k].top())
q[x][k].pop(),e[x][k].pop();
} inline void erase(int x,int s,int er){
int now=-;
if(fat[x]){
if(vis[er])
e[x][].push(lca(er,fat[x]));
else
q[x][].push(lca(er,fat[x]));
clear(x,);
erase(fat[x],x,er);
}
if(s) {
if(q[s][].empty()^)
now=q[s][].top();
if(lasttop[s]!=now){
if(lasttop[s]!=-)
e[x][].push(lasttop[s]);
if(now!=-)
q[x][].push(now);
}else return;
lasttop[s]=now;
}
clear(x,);
now=-;
if(q[x][].empty()^){
int a1=q[x][].top();
q[x][].pop();
clear(x,);
if(q[x][].empty()^)
now=a1+q[x][].top();
else if(!vis[x]) now=a1;
q[x][].push(a1);
}
if(lastans[x]!=now){
if(lastans[x]!=-)
anse.push(lastans[x]);
if(now!=-)
ans.push(now);
}lastans[x]=now;
} inline void update(int x){
vis[x]^=;
if(vis[x]) --tot;
else ++tot;
erase(x,,x);
} int main(){
n=read();
register int i;
for(i=;i^n;++i){
int a=read(),b=read();
push(a,b),push(b,a);
}
for(i=;i^;++i) bit[i]=<<i;
memset(lastans,-,sizeof(lastans));
memset(lasttop,-,sizeof(lasttop));
dfs();tot=n;
build(,);
memset(vis,,sizeof(vis));
tot=n;
m=read();
while(m--){
char opt[];
scanf("%s",opt);
if(opt[]=='G') putans();
else update(read());
}
}
【bzoj 1095】[ZJOI2007]Hide 捉迷藏的更多相关文章
- 【刷题】BZOJ 1095 [ZJOI2007]Hide 捉迷藏
Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏
Description 一棵树,支持两个操作,修改一个点的颜色,问树上最远的两个白点距离. Sol 动态点分治. 动态点分治就是将每个重心连接起来,形成一个跟线段树类似的结构,当然它不是二叉的... ...
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...
- 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)
题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)
这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...
- BZOJ 1095 [ZJOI2007]Hide 捉迷藏 ——动态点分治
[题目分析] 这题好基啊. 先把分治树搞出来.然后每个节点两个堆. 第一个堆保存这个块里的所有点(即分治树中的所有儿子)到分治树上的父亲的距离. 第二个堆保存分治树子树中所有儿子第一个堆的最大值. 建 ...
- [BZOJ 1095] [ZJOI2007]Hide 捉迷藏——线段树+括号序列(强..)
神做法-%dalao,写的超详细 konjac的博客. 如果觉得上面链接的代码不够优秀好看,欢迎回来看本蒟蒻代码- CODE WITH ANNOTATION 代码中−6-6−6表示左括号'[',用−9 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏 动态点分治+堆
写了7k多,可以说是一己之力切掉了这道毒瘤题~ 开 $3$ 种堆,分别维护每个子树最大深度,以及每个节点在点分树中对父亲的贡献,和全局的最优解. 由于需要支持堆的删除,所以写起来特别恶心+麻烦. 细节 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏(动态点分治)
传送门 解题思路 点分树其实就是在点分治的基础上,把重心连起来.这样树高是\(log\)的,可以套用数据结构进行操作.这道题是求最远距离,所以每个点维护两个堆,分别表示所管辖的子树的最远距离和到父节点 ...
随机推荐
- Set对象常用操作方法和遍历
Set<String> set = new HashSet<String>(); /** * set的常用操作方法有: * add()向集合添加元素 clear()清空集合元素 ...
- SQL 逻辑优化 case when 转为 union all
通常数据库的优化从硬件层面去考虑可分为4个方面: CPU:即降低计算复杂度,如减少sql各类聚合函数,窗口函数,case when等. IO :(较少查询结果集过程中对数据的访问量.数据优化很大程度从 ...
- Go中string转[]byte的陷阱
Go中string转[]byte的陷阱html {overflow-x: initial !important;}#write, body { height: auto; }#write, #writ ...
- 了解与建设有中国特色的Android M&N(Android6.0和7.0新特性分析)
http://geek.csdn.NET/news/detail/110434 Android N已经发布有段时间,甚至马上都要发布android 7.1,相信不少玩机爱好者已经刷入最新的Androi ...
- UE4中创建第一、第三人称角色,并进行角色间的切换
在游戏中经常会出现第一人称和第三人称的视角切换场景,笔者在这里简单介绍如何进行这步操作. 1.创建角色 在内容浏览器中添加2个Character蓝图,分别命名为FirstPersonalCharact ...
- leetCode刷题(找到两个数组拼接后的中间数)
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- 如何通过CSS实现背景图片自动平铺或拉伸至整个屏幕(自适应大小)
默认情况下,通过HTML代码的BODY标签设置好背景图片<body background="x.jpg"> 后,图片会自动横向和纵向平铺.这就会产生一些美观上的问题. ...
- Flask入门之flask-wtf表单处理
参考文章 1. 使用 WTForms 进行表单验证 第11集 #Sample.py # coding:utf-8 from flask import Flask,render_template,re ...
- 单片机开发——03工欲善其事必先利其器(AD软件安装破解)
在单片机开发中,有了Keil的程序编程,Protues的模拟仿真,那么问题来了,怎么去进行电路图设计以及硬件调试呢?此刻就必须引入本文的Altium Designer (下文简称AD)安装与破解.在硬 ...
- 设计模式的征途—17.模板方法(Template Method)模式
在现实生活中,很多事情都需要经过几个步骤才能完成,例如请客吃饭,无论吃什么,一般都包含:点单.吃东西.买单等几个步骤,通常情况下这几个步骤的次序是:点单=>吃东西=>买单.在这3个步骤中, ...