题解:

好像还是比较简单的

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

树高是log的

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

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

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

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

修改是nlog^2的

洛谷上的时限真紧啊。。

卡时卡不过

 代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=2e5+;
  4. const int INF=1e9;
  5. #define IL inline
  6. #define rint register int
  7. #define rep(i,h,t) for (rint i=h;i<=t;i++)
  8. #define dep(i,t,h) for (ritn i=t;i>=h;i--)
  9. char ss[<<],*A=ss,*B=ss;
  10. IL char gc()
  11. {
  12. return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
  13. }
  14. template<class T>IL void read(T &x)
  15. {
  16. rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
  17. while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
  18. }
  19. IL void read2(char &x)
  20. {
  21. rint c; while (c=gc(),c!='G'&&c!='C'); x=c;
  22. }
  23. char sr[<<],z[]; int C=-,Z;
  24. template <class T> void wer(T x)
  25. {
  26. if (x<) sr[++C]='-',x=-x;
  27. while (z[++Z]=x%+,x/=);
  28. while (sr[++C]=z[Z],--Z); sr[++C]='\n';
  29. }
  30. struct PQ{
  31. struct cmp{
  32. IL bool operator() (int x,int y)
  33. {
  34. return(x<y);
  35. }
  36. };
  37. priority_queue<int>Q1,Q2;
  38. IL void push(int x) {Q1.push(x);}
  39. IL void erase(int x) {Q2.push(x);}
  40. IL int top()
  41. {
  42. while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
  43. if (Q1.size()) return(Q1.top()); else return(-INF);
  44. }
  45. IL void pop()
  46. {
  47. while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
  48. Q1.pop();
  49. }
  50. IL int sec_top()
  51. {
  52. int tmp=top();
  53. if (tmp>) pop();
  54. int x=top();
  55. if (tmp>) push(tmp);
  56. return x;
  57. }
  58. }Q1[N],Q2[N],QQ;
  59. int n,l,head[N],dep[N],bz[][N],f[N],son[N],fa[N],rt,ans1[N],ans2[N];
  60. int sum;
  61. bool vis[N];
  62. struct re{
  63. int a,b;
  64. }a[N*];
  65. void arr(int x,int y)
  66. {
  67. a[++l].a=head[x];
  68. a[l].b=y;
  69. head[x]=l;
  70. }
  71. IL int lca(int x,int y)
  72. {
  73. if (dep[x]<dep[y]) swap(x,y);
  74. for (int i=;i>=;i--)
  75. if (dep[bz[i][x]]>=dep[y]) x=bz[i][x];
  76. if (x==y) return(x);
  77. for (int i=;i>=;i--)
  78. if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y];
  79. return(bz[][x]);
  80. }
  81. IL int js(int x,int y)
  82. {
  83. int kk=lca(x,y);
  84. return(dep[x]+dep[y]-*dep[kk]);
  85. }
  86. void dfs(int x,int fa)
  87. {
  88. int u=head[x]; dep[x]=dep[fa]+; bz[][x]=fa;
  89. while (u)
  90. {
  91. int v=a[u].b;
  92. if (v!=fa) dfs(v,x);
  93. u=a[u].a;
  94. }
  95. }
  96. void fr(int x,int fa)
  97. {
  98. f[x]=; son[x]=;
  99. int u=head[x];
  100. while (u)
  101. {
  102. int v=a[u].b;
  103. if (v!=fa&&vis[v])
  104. {
  105. fr(v,x);
  106. f[x]=max(f[x],son[v]);
  107. son[x]+=son[v];
  108. }
  109. u=a[u].a;
  110. }
  111. f[x]=max(f[x],sum-son[x]);
  112. if (f[x]<f[rt]) rt=x;
  113. }
  114. void fd(int x,int y,int kk,int z)
  115. {
  116. int jl=js(x,kk);
  117. Q1[z].push(jl);
  118. int u=head[x];
  119. while (u)
  120. {
  121. int v=a[u].b;
  122. if (v!=y&&vis[v]) fd(v,x,kk,z);
  123. u=a[u].a;
  124. }
  125. }
  126. void solve(int x,int y,int z)
  127. {
  128. //cout<<z<<endl;
  129. int u=head[x]; fa[x]=y; vis[x]=;
  130. if (x!=)
  131. {
  132. fd(x,y,y,x),Q2[y].push(Q1[x].top());
  133. ans1[x]=Q1[x].top();
  134. }
  135. Q2[x].push();
  136. while (u)
  137. {
  138. int v=a[u].b;
  139. if (vis[v])
  140. {
  141. rt=; sum=son[v];
  142. fr(v,x);
  143. solve(rt,x,z+);
  144. }
  145. u=a[u].a;
  146. }
  147. }
  148. int cnt1,cnt2;
  149. IL int cl(int x,int y)
  150. {
  151. cnt1++;
  152. if (y>ans1[x])
  153. {
  154. Q2[fa[x]].erase(ans1[x]);
  155. ans1[x]=y;
  156. Q2[fa[x]].push(ans1[x]);
  157. return();
  158. }
  159. return();
  160. }
  161. IL int cl3(int x,int y)
  162. {
  163. if (y==ans1[x])
  164. {
  165. Q2[fa[x]].erase(ans1[x]);
  166. ans1[x]=Q1[x].top();
  167. Q2[fa[x]].push(ans1[x]);
  168. return();
  169. }
  170. return();
  171. }
  172. IL void cl2(int x)
  173. {
  174. cnt2++;
  175. int num=Q2[x].top()+Q2[x].sec_top();
  176. if (num!=ans2[x])
  177. {
  178. if (ans2[x]>) QQ.erase(ans2[x]);
  179. ans2[x]=num;
  180. if (ans2[x]>) QQ.push(ans2[x]);
  181. }
  182. }
  183. IL void change(int x,int y)
  184. {
  185. if (y==) Q2[x].push(); else Q2[x].erase();
  186. cl2(x);
  187. rint z=x;
  188. while (z!=)
  189. {
  190. rint jl=js(x,fa[z]);
  191. if (y==)
  192. {
  193. Q1[z].push(jl);
  194. if (cl(z,jl)) cl2(fa[z]);
  195. } else
  196. {
  197. Q1[z].erase(jl);
  198. if (cl3(z,jl)) cl2(fa[z]);
  199. }
  200. z=fa[z];
  201. }
  202. }
  203. bool t[N];
  204. int main()
  205. {
  206. freopen("1.in","r",stdin);
  207. freopen("1.out","w",stdout);
  208. // ios::sync_with_stdio(false);
  209. read(n);
  210. for (int i=;i<=n-;i++)
  211. {
  212. int x,y;
  213. read(x); read(y); arr(x,y); arr(y,x);
  214. }
  215. memset(vis,,sizeof(vis));
  216. dfs(,);
  217. rep(i,,)
  218. rep(j,,n)
  219. bz[i][j]=bz[i-][bz[i-][j]];
  220. f[]=INF; solve(,,);
  221. rep(i,,n)
  222. {
  223. int num; num=ans2[i]=Q2[i].top()+Q2[i].sec_top();
  224. if (num>) QQ.push(num);
  225. }
  226. memset(t,,sizeof(t));
  227. int m;
  228. read(m);
  229. char kk;
  230. rep(i,,m)
  231. {
  232. int x;
  233. read2(kk);
  234. if (kk=='G')
  235. {
  236. wer(QQ.top());
  237. } else
  238. {
  239. read(x);
  240. if (t[x]==)
  241. {
  242. t[x]=;
  243. change(x,);
  244. } else
  245. {
  246. t[x]=;
  247. change(x,);
  248. }
  249. }
  250. }
  251. // cout<<cnt1<<endl<<cnt2<<endl;
  252. fwrite(sr,,C+,stdout);
  253. return ;
  254. }

【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. _tcsdup这个函数容易出现堆错误

    #include <string.h> #include <stdio.h> #include <tchar> int main( void ) { TCHAR b ...

  2. 搭建基于IDEA+Selenium+Java+TestNG+Maven+Jenkins+SVN的Web端UI自动化测试环境

    第一步:工具下载安装配置 JDK安装与配置 IDEA安装与配置 Maven安装与配置 Tomcat部署与配置 Jenkins部署与配置 Svn安装与配置 各浏览器驱动下载与配置 第二步:集成各个工具到 ...

  3. 前端 -----02 body标签中相关标签

    今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...

  4. MySQL跟踪SQL执行之开启慢查询日志

      查询慢查询相关参数   show variables like '%quer%';   slow_query_log(是否记录慢查询)   slow_query_log_file(慢日志文件路径) ...

  5. 使用第三方组件(django-redis)创建连接池

    settings里面: ##redis配置CACHES={ 'default':{ 'BACKEND':'django_redis.cache.RedisCache', 'LOCATION':'red ...

  6. PID控制器开发笔记之十一:专家PID控制器的实现

    前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...

  7. Modbus库开发笔记之一:实现功能的基本设计

    Modbus作为开放式的工业通讯协议,在各种工业设备中应用极其广泛.本人也使用Modbus通讯很多年了,或者用现成的,或者针对具体应用开发,一直以来都想要开发一个比较通用的协议栈能在后续的项目中复用, ...

  8. 基于 Confluence 6 数据中心在你的 Atlassian 应用中配置 SAML 授权

    希望在 Confluence 中配置SAML: Go to  > 基本配置(General Configuration) > SAMl 授权(SAML Authentication). 选 ...

  9. LeetCode(74):搜索二维矩阵

    Medium! 题目描述: 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例  ...

  10. LeetCode(72):编辑距离

    Hard! 题目描述: 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替换 ...