题解:

好像还是比较简单的

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

树高是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. JQuery 拾遗

    jquery基本上依赖百度,不熟悉的jquery操作记录于此: 1.判断元素的显示隐藏:$("#XXX").is(':visible'). 2. jquery取所有属性以什么开头 ...

  2. 在 C# 中,(int) ,Int32.Parse() 和 Convert.toInt32() 三种方法的区别

    在 C# 中,(int),Int32.Parse() 和 Convert.toInt32() 三种方法有何区别? int 关键字表示一种整型,是32位的,它的 .NET Framework 类型为 S ...

  3. Openssl编程--源码分析

    Openssl编程 赵春平 著 Email: forxy@126.com 第一章 基础知识 8 1.1 对称算法 8 1.2 摘要算法 9 1.3 公钥算法 9 1.4 回调函数 11 第二章 ope ...

  4. [Linux]关于字节序的解析

    剥鸡蛋的故事 <格列佛游记>中记载了两个征战的强国,你不会想到的是,他们打仗竟然和剥鸡蛋的姿势有关. 很多人认为,剥鸡蛋时应该打破鸡蛋较大的一端,这群人被称作“大端(Big endian) ...

  5. 牛客网 python 求解立方根

    •计算一个数字的立方根,不使用库函数 详细描述: •接口说明 原型: public static double getCubeRoot(double input) 输入:double 待求解参数 返回 ...

  6. Android:四大架构的优缺点,你真的了解吗?

    声明|转载于作者:KunMinX原文链接:https://www.jianshu.com/p/9ef813d5c1af 前言 前不久刚结束对 20 模块项目的第 3 轮重构,一路见证 MVC.MVP. ...

  7. JS打开新的窗口

    一.使用JS打开新窗口 1. 超链接<a href="http://www.wumz.me" title="Mauger`s Blog">Welco ...

  8. css中border画三角形

    <!doctype html><html lang="en"> <head>  <meta charset="UTF-8&quo ...

  9. matlab提取wind底层数据库操作

    首先需要安装navicat for SQL server 软件, 为了实现Matlab 通过JDBC方式连接Sqlserver数据库, 需要安装Sqlserver JDBC驱动. 地址: https: ...

  10. cf869C组合计数问题

    如果在两个区域里连点,两个区域内选的点数一定要相等 即a中选出i个点,必须与b中选出i个点相连 连接种类数为  然后我们再来看,如果ab中有两点相连,其中一点再与c相连会出事吗? 很显然不会对答案产生 ...