题解:

好像还是比较简单的

对每个重心向下一层重心连边

树高是log的

我们对每一层维护两个信息

1.所有节点到上一层重心的距离

2.所有儿子的1堆的堆顶

另外开个总的堆 维护每一层最长+次长

修改是nlog^2的

洛谷上的时限真紧啊。。

卡时卡不过

 代码:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+;
const int INF=1e9;
#define IL inline
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (ritn i=t;i>=h;i--)
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T>IL void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
IL void read2(char &x)
{
rint c; while (c=gc(),c!='G'&&c!='C'); x=c;
}
char sr[<<],z[]; int C=-,Z;
template <class T> void wer(T x)
{
if (x<) sr[++C]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C]=z[Z],--Z); sr[++C]='\n';
}
struct PQ{
struct cmp{
IL bool operator() (int x,int y)
{
return(x<y);
}
};
priority_queue<int>Q1,Q2;
IL void push(int x) {Q1.push(x);}
IL void erase(int x) {Q2.push(x);}
IL int top()
{
while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
if (Q1.size()) return(Q1.top()); else return(-INF);
}
IL void pop()
{
while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
Q1.pop();
}
IL int sec_top()
{
int tmp=top();
if (tmp>) pop();
int x=top();
if (tmp>) push(tmp);
return x;
}
}Q1[N],Q2[N],QQ;
int n,l,head[N],dep[N],bz[][N],f[N],son[N],fa[N],rt,ans1[N],ans2[N];
int sum;
bool vis[N];
struct re{
int a,b;
}a[N*];
void arr(int x,int y)
{
a[++l].a=head[x];
a[l].b=y;
head[x]=l;
}
IL int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
for (int i=;i>=;i--)
if (dep[bz[i][x]]>=dep[y]) x=bz[i][x];
if (x==y) return(x);
for (int i=;i>=;i--)
if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y];
return(bz[][x]);
}
IL int js(int x,int y)
{
int kk=lca(x,y);
return(dep[x]+dep[y]-*dep[kk]);
}
void dfs(int x,int fa)
{
int u=head[x]; dep[x]=dep[fa]+; bz[][x]=fa;
while (u)
{
int v=a[u].b;
if (v!=fa) dfs(v,x);
u=a[u].a;
}
}
void fr(int x,int fa)
{
f[x]=; son[x]=;
int u=head[x];
while (u)
{
int v=a[u].b;
if (v!=fa&&vis[v])
{
fr(v,x);
f[x]=max(f[x],son[v]);
son[x]+=son[v];
}
u=a[u].a;
}
f[x]=max(f[x],sum-son[x]);
if (f[x]<f[rt]) rt=x;
}
void fd(int x,int y,int kk,int z)
{
int jl=js(x,kk);
Q1[z].push(jl);
int u=head[x];
while (u)
{
int v=a[u].b;
if (v!=y&&vis[v]) fd(v,x,kk,z);
u=a[u].a;
}
}
void solve(int x,int y,int z)
{
//cout<<z<<endl;
int u=head[x]; fa[x]=y; vis[x]=;
if (x!=)
{
fd(x,y,y,x),Q2[y].push(Q1[x].top());
ans1[x]=Q1[x].top();
}
Q2[x].push();
while (u)
{
int v=a[u].b;
if (vis[v])
{
rt=; sum=son[v];
fr(v,x);
solve(rt,x,z+);
}
u=a[u].a;
}
}
int cnt1,cnt2;
IL int cl(int x,int y)
{
cnt1++;
if (y>ans1[x])
{
Q2[fa[x]].erase(ans1[x]);
ans1[x]=y;
Q2[fa[x]].push(ans1[x]);
return();
}
return();
}
IL int cl3(int x,int y)
{
if (y==ans1[x])
{
Q2[fa[x]].erase(ans1[x]);
ans1[x]=Q1[x].top();
Q2[fa[x]].push(ans1[x]);
return();
}
return();
}
IL void cl2(int x)
{
cnt2++;
int num=Q2[x].top()+Q2[x].sec_top();
if (num!=ans2[x])
{
if (ans2[x]>) QQ.erase(ans2[x]);
ans2[x]=num;
if (ans2[x]>) QQ.push(ans2[x]);
}
}
IL void change(int x,int y)
{
if (y==) Q2[x].push(); else Q2[x].erase();
cl2(x);
rint z=x;
while (z!=)
{
rint jl=js(x,fa[z]);
if (y==)
{
Q1[z].push(jl);
if (cl(z,jl)) cl2(fa[z]);
} else
{
Q1[z].erase(jl);
if (cl3(z,jl)) cl2(fa[z]);
}
z=fa[z];
}
}
bool t[N];
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
// ios::sync_with_stdio(false);
read(n);
for (int i=;i<=n-;i++)
{
int x,y;
read(x); read(y); arr(x,y); arr(y,x);
}
memset(vis,,sizeof(vis));
dfs(,);
rep(i,,)
rep(j,,n)
bz[i][j]=bz[i-][bz[i-][j]];
f[]=INF; solve(,,);
rep(i,,n)
{
int num; num=ans2[i]=Q2[i].top()+Q2[i].sec_top();
if (num>) QQ.push(num);
}
memset(t,,sizeof(t));
int m;
read(m);
char kk;
rep(i,,m)
{
int x;
read2(kk);
if (kk=='G')
{
wer(QQ.top());
} else
{
read(x);
if (t[x]==)
{
t[x]=;
change(x,);
} else
{
t[x]=;
change(x,);
}
}
}
// cout<<cnt1<<endl<<cnt2<<endl;
fwrite(sr,,C+,stdout);
return ;
}

【BZOJ1095】【ZJOI2007】捉迷藏 [动态点分治]的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ1095:[ZJOI2007]Hide 捉迷藏(动态点分治)

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

  6. 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)

    题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...

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

    [题目分析] 这题好基啊. 先把分治树搞出来.然后每个节点两个堆. 第一个堆保存这个块里的所有点(即分治树中的所有儿子)到分治树上的父亲的距离. 第二个堆保存分治树子树中所有儿子第一个堆的最大值. 建 ...

  8. BZOJ 1095: [ZJOI2007]Hide 捉迷藏(动态点分治)

    传送门 解题思路 点分树其实就是在点分治的基础上,把重心连起来.这样树高是\(log\)的,可以套用数据结构进行操作.这道题是求最远距离,所以每个点维护两个堆,分别表示所管辖的子树的最远距离和到父节点 ...

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

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

随机推荐

  1. C# string.join

    String.Join 方法 平常工作中经常用到string.join()方法,在vs 2017用的运行时(System.Runtime, Version=4.2.0.0)中,共有九个(重载)方法. ...

  2. u3d人物控制

    //https://blog.csdn.net/Htlas/article/details/79188008 //人物移动 http://gad.qq.com/article/detail/28921 ...

  3. 题解-UOJ284 快乐游戏鸡

    Problem uoj 题意大意: 一棵树,点权\(w_i\),每次玩家可以在树上行走,一条边需要\(1\)的时间,只能往儿子走.每次游戏需要从\(s\)到\(t\). 玩家有一个总死亡次数,初始为\ ...

  4. win32编程中消息循环和WndProc()窗口过程函数

    原文地址:https://blog.csdn.net/zxxSsdsd/article/details/45504383 在win32程序的消息循环函数中  while (GetMessage (&a ...

  5. 制作缩略图java工具类

    import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.File ...

  6. Golang -- range小坑铭记

    废话少叙,先上一段代码,猜猜预期的效果. package main import ( "fmt" ) type student struct { Name string Age i ...

  7. Kali Linux2018 上安装open-vm-tools实现虚拟机交互

    最新的kali linux2018已经不再支持原有的vmwaretools,即使安装了也不能实现主机与客户机之间的交互(比如从主机复制文件到客户机).安装open-vm-tools替代vm tools ...

  8. DHTMLX Tree中文开发指导

    专业版1.6下载地址(CSDN) http://download.csdn.net/source/1388340 版本号:dhtmlxTree v.1.6 Professional edition b ...

  9. .NET基础之构造函数

    1.构造函数: 分为实例构造函数.静态构造函数.私有构造函数. 使用new表达式创建某个类的对象时, 1.1实例构造函数: (1)构造函数的名字与类名相同: (2)使用new表达式创建类的对象或者结构 ...

  10. winfrom里面打印类似小票

    首先在窗体上拖一个printDocument1控件和一个Button按钮,然后双击该控件的PrintPage事件,在事件里面复制下面代码: Pen blackPen = new Pen(Color.B ...