【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$ 种堆,分别维护每个子树最大深度,以及每个节点在点分树中对父亲的贡献,和全局的最优解. 由于需要支持堆的删除,所以写起来特别恶心+麻烦. 细节 ...
随机推荐
- _tcsdup这个函数容易出现堆错误
#include <string.h> #include <stdio.h> #include <tchar> int main( void ) { TCHAR b ...
- 搭建基于IDEA+Selenium+Java+TestNG+Maven+Jenkins+SVN的Web端UI自动化测试环境
第一步:工具下载安装配置 JDK安装与配置 IDEA安装与配置 Maven安装与配置 Tomcat部署与配置 Jenkins部署与配置 Svn安装与配置 各浏览器驱动下载与配置 第二步:集成各个工具到 ...
- 前端 -----02 body标签中相关标签
今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...
- MySQL跟踪SQL执行之开启慢查询日志
查询慢查询相关参数 show variables like '%quer%'; slow_query_log(是否记录慢查询) slow_query_log_file(慢日志文件路径) ...
- 使用第三方组件(django-redis)创建连接池
settings里面: ##redis配置CACHES={ 'default':{ 'BACKEND':'django_redis.cache.RedisCache', 'LOCATION':'red ...
- PID控制器开发笔记之十一:专家PID控制器的实现
前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...
- Modbus库开发笔记之一:实现功能的基本设计
Modbus作为开放式的工业通讯协议,在各种工业设备中应用极其广泛.本人也使用Modbus通讯很多年了,或者用现成的,或者针对具体应用开发,一直以来都想要开发一个比较通用的协议栈能在后续的项目中复用, ...
- 基于 Confluence 6 数据中心在你的 Atlassian 应用中配置 SAML 授权
希望在 Confluence 中配置SAML: Go to > 基本配置(General Configuration) > SAMl 授权(SAML Authentication). 选 ...
- LeetCode(74):搜索二维矩阵
Medium! 题目描述: 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例 ...
- LeetCode(72):编辑距离
Hard! 题目描述: 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替换 ...