【BZOJ1095】【ZJOI2007】捉迷藏 [动态点分治]
题解:
好像还是比较简单的
对每个重心向下一层重心连边
树高是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】捉迷藏 [动态点分治]的更多相关文章
- 【BZOJ1095】[ZJOI2007]Hide 捉迷藏 动态树分治+堆
[BZOJ1095][ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉 ...
- BZOJ1095 [ZJOI2007]Hide 捉迷藏 动态点分治 堆
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ1095.html 题目传送门 - BZOJ1095 题意 有 N 个点,每一个点是黑色或者白色,一开始所 ...
- 【bzoj1095】[ZJOI2007]Hide 捉迷藏 动态点分治+堆
题目描述 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这 ...
- bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习
好迷啊...感觉动态点分治就是个玄学,蜜汁把树的深度缩到logn (静态)点分治大概是递归的时候分类讨论: 1.答案经过当前点,暴力(雾)算 2.答案不经过当前点,继续递归 由于原树可以长的奇形怪状( ...
- BZOJ1095:[ZJOI2007]Hide 捉迷藏(动态点分治)
Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...
- 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)
题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...
- BZOJ 1095 [ZJOI2007]Hide 捉迷藏 ——动态点分治
[题目分析] 这题好基啊. 先把分治树搞出来.然后每个节点两个堆. 第一个堆保存这个块里的所有点(即分治树中的所有儿子)到分治树上的父亲的距离. 第二个堆保存分治树子树中所有儿子第一个堆的最大值. 建 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏(动态点分治)
传送门 解题思路 点分树其实就是在点分治的基础上,把重心连起来.这样树高是\(log\)的,可以套用数据结构进行操作.这道题是求最远距离,所以每个点维护两个堆,分别表示所管辖的子树的最远距离和到父节点 ...
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏 动态点分治+堆
写了7k多,可以说是一己之力切掉了这道毒瘤题~ 开 $3$ 种堆,分别维护每个子树最大深度,以及每个节点在点分树中对父亲的贡献,和全局的最优解. 由于需要支持堆的删除,所以写起来特别恶心+麻烦. 细节 ...
随机推荐
- MongoDB与MySQL的插入、查询性能测试
1.1 MongoDB的简单介绍 在当今的数据库市场上,MySQL无疑是占有一席之地的.作为一个开源的关系型数据库,MySQL被大量应用在各大网站后台中,承担着信息存储的重要作用.2009年,甲骨文 ...
- $Django 模板层(模板导入,继承)、 单表*详(增删改查,基于双下划线的查询)、static之静态文件配置
0在python脚本中使用django环境 import osif __name__ == '__main__': os.environ.setdefault("DJANGO_SETT ...
- Python2018-字符串中字符个数统计
1 编写程序,完成以下要求: 统计字符串中,各个字符的个数 比如:"hello world" 字符串统计的结果为: h:1 e:1 l:3 o:2 d:1 r:1 w:1 prin ...
- RocketMQ实战快速入门
转自:https://www.jianshu.com/p/824066d70da8 一.RocketMQ 是什么 Github 上关于 RocketMQ 的介绍:RcoketMQ 是一款低延 ...
- 【原创】大数据基础之Flume(2)kudu sink
kudu中的flume sink代码路径: https://github.com/apache/kudu/tree/master/java/kudu-flume-sink kudu-flume-sin ...
- [MySQL]group by 与 having 结合函数 的统计技巧
group by 与 having 允许字段使用函数,根据函数运行的结果group by分组或having设置选择条件; 同时group by 与 having 也允许使用字段别名 示例表a: id ...
- layui 左侧三级菜单栏
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Redis重大版本
Redis借鉴了Linux操作系统对于版本号的命名规则: 版本号第二位如果是奇数,则为非稳定版本(例如2.7.2.9.3.1),如果是偶数,则为稳定版本(例如2.6.2.8.3.0.3.2), 当前奇 ...
- GoLand使用
# 不定期更新 什么是GoLand GoLand是JetBrains出品的一个Go语言IDE,JB的IDE有多好用我想很多程序员都知道,个人感觉唯一的缺点就是比较大(因为功能多) 希望大家多多支持正版 ...
- Confluence 6 查看一个任务的执行历史
希望查看一个计划任务最后运行的时间和这个计划任务最后一次运行花费了多长时间.单击计划任务边上的 历史(History )连接. 如果一个计划任务从来没有运行的胡啊,那么这个历史的链接是不会显示的. 屏 ...