动态树分治,用三个set分别维护每个重心到每一个子树的距离种类、每个重心所有子树的最大值和次大值、全局答案的最大值。复杂度O(nlogn^2)

  代码

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<vector>
  4. #include<set>
  5. #define pb push_back
  6. using namespace std;
  7. const int N = ;
  8. int size[N],flag[N],n,a,b,i,f[N],cnt,typ[N],deep[N];
  9. int jump[N][];
  10. int q;
  11. char ch[];
  12. vector<int> e[N];
  13. multiset<int> dist[N],ans[N],Ans;
  14. multiset<int>::iterator it;
  15. int getroot(int x,int fa,int n)
  16. {
  17. int i,tmp=,rt=;
  18. size[x]=;
  19. for (i=;i<e[x].size();i++)
  20. if ((e[x][i]!=fa)&&(!flag[e[x][i]]))
  21. {
  22. rt|=getroot(e[x][i],x,n);
  23. size[x]+=size[e[x][i]];
  24. if (size[e[x][i]]>n/) tmp=;
  25. }
  26. if (n-size[x]>n/) tmp=;
  27. if (tmp==) return rt;else return x;
  28. }
  29. void gao(int x,int fa,int y,int dis)
  30. {
  31. dis++;
  32. int i;
  33. dist[y].insert(dis);
  34. for (i=;i<e[x].size();i++)
  35. if ((!flag[e[x][i]])&&(e[x][i]!=fa))
  36. gao(e[x][i],x,y,dis);
  37. }
  38. void DFS(int x,int fa)
  39. {
  40. int i;
  41. deep[x]=deep[fa]+;
  42. jump[x][]=fa;
  43. for (i=;i<=;i++)
  44. jump[x][i]=jump[jump[x][i-]][i-];
  45. for (i=;i<e[x].size();i++)
  46. if (e[x][i]!=fa) DFS(e[x][i],x);
  47. }
  48. int lca(int a,int b)
  49. {
  50. int i;
  51. if (deep[a]<deep[b]) a^=b^=a^=b;
  52. for (i=;i>=;i--)
  53. if (deep[jump[a][i]]>=deep[b]) a=jump[a][i];
  54. if (a==b) return a;
  55. for (i=;i>=;i--)
  56. if (jump[a][i]!=jump[b][i]) a=jump[a][i],b=jump[b][i];
  57. return jump[a][];
  58. }
  59. int getdis(int x,int y)
  60. {
  61. int z=lca(x,y);
  62. return deep[x]+deep[y]-*deep[z];
  63. }
  64. void del(int x)
  65. {
  66. int tmp=;
  67. if (ans[x].size()>=)
  68. {
  69. it=ans[x].end();
  70. --it;tmp+=*it;
  71. --it;tmp+=*it;
  72. it=Ans.lower_bound(tmp);
  73. Ans.erase(it);
  74. }
  75. }
  76. void ins(int x)
  77. {
  78. int tmp=;
  79. if (ans[x].size()>=)
  80. {
  81. it=ans[x].end();
  82. --it;tmp+=*it;
  83. --it;tmp+=*it;
  84. Ans.insert(tmp);
  85. }
  86. }
  87. void DEL(int y)
  88. {
  89. if (dist[y].size())
  90. {
  91. it=dist[y].end();--it;
  92. int tmp=*it;
  93. it=ans[f[y]].lower_bound(tmp);
  94. ans[f[y]].erase(it);
  95. }
  96. }
  97. void INS(int y)
  98. {
  99. if (dist[y].size())
  100. {
  101. it=dist[y].end();--it;
  102. int tmp=*it;
  103. ans[f[y]].insert(tmp);
  104. }
  105. }
  106. int change(int x,int y)
  107. {
  108. del(x);
  109. if (typ[x]==)
  110. {
  111. it=ans[x].lower_bound();
  112. ans[x].erase(it);
  113. }
  114. else
  115. ans[x].insert();
  116. while (x)
  117. {
  118. ins(x);
  119. if (f[x])
  120. {
  121. del(f[x]);
  122. DEL(x);
  123. int dis=getdis(f[x],y);
  124. if (typ[y]==)
  125. {
  126. it=dist[x].lower_bound(dis);
  127. dist[x].erase(it);
  128. }
  129. else
  130. dist[x].insert(dis);
  131. INS(x);
  132. }
  133. x=f[x];
  134. }
  135. }
  136. int dfs(int x,int n,int fa)
  137. {
  138. int i,y;
  139. x=getroot(x,,n);
  140. f[x]=fa;
  141. flag[x]=;
  142. ans[x].insert();
  143. for (i=;i<e[x].size();i++)
  144. if (!flag[e[x][i]])
  145. {
  146. if (size[e[x][i]]>size[x])
  147. y=dfs(e[x][i],n-size[x],x);
  148. else
  149. y=dfs(e[x][i],size[e[x][i]],x);
  150. gao(e[x][i],,y,);
  151. it=dist[y].end();
  152. ans[x].insert(*(--it));
  153. }
  154. ins(x);
  155. flag[x]=;
  156. return x;
  157. }
  158. int main()
  159. {
  160. scanf("%d",&n);
  161. for (i=;i<n;i++)
  162. {
  163. scanf("%d%d",&a,&b);
  164. e[a].pb(b);
  165. e[b].pb(a);
  166. }
  167. dfs(,n,);
  168. DFS(,);
  169. scanf("%d",&q);
  170. for (i=;i<=q;i++)
  171. {
  172. scanf("%s",ch+);
  173. if (ch[]=='G')
  174. {
  175. if (cnt==n)
  176. printf("-1\n");
  177. else
  178. if (cnt==n-)
  179. printf("0\n");
  180. else
  181. {
  182. it=Ans.end();--it;
  183. printf("%d\n",*it);
  184. }
  185. }
  186. else
  187. if (ch[]=='C')
  188. {
  189. scanf("%d",&a);
  190. if (typ[a]==)
  191. cnt++,typ[a]=;
  192. else
  193. cnt--,typ[a]=;
  194. change(a,a);
  195. }
  196. }
  197. }

BZOJ1095 [ZJOI2007]Hide 捉迷藏的更多相关文章

  1. 动态点分治:Bzoj1095: [ZJOI2007]Hide 捉迷藏

    简介 这是我自己的一点理解,可能写的不好 点分治都学过吧.. 点分治每次找重心把树重新按重心的深度重建成了一棵新的树,称为分治树 这个树最多有log层... 动态点分治:记录下每个重心的上一层重心,这 ...

  2. [bzoj1095][ZJOI2007]Hide 捉迷藏 点分树,动态点分治

    [bzoj1095][ZJOI2007]Hide 捉迷藏 2015年4月20日7,8876 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiaji ...

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

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

  4. BZOJ1095: [ZJOI2007]Hide 捉迷藏【线段树维护括号序列】【思维好题】

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

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

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

  6. bzoj千题计划245:bzoj1095: [ZJOI2007]Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 查询最远点对,带修改 显然可以用动态点分治 对于每个点,维护两个堆 堆q1[x] 维护 点分树 ...

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

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

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

    题目链接 BZOJ1095 题解 传说中的动态点分治,一直不敢碰 今日一会,感觉其实并不艰涩难懂 考虑没有修改,如果不用树形dp的话,就得点分治 对于每个重心,我们会考虑其分治的子树内所有点到它的距离 ...

  9. bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治

    这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节.. 点分治:时空复杂度$O(n\log^2n)$,常数巨大 主要就是3个堆的初始状态 C堆:每个节点一个,为子树中的点到它父亲的距离的堆. B ...

随机推荐

  1. BC一周年练习赛

    Souvenir  Accepts: 901  Submissions: 2743  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 262 ...

  2. XVI Open Cup named after E.V. Pankratiev. GP of SPB

    A. Bubbles 枚举两个点,求出垂直平分线与$x$轴的交点,答案=交点数+1. 时间复杂度$O(n^2\log n)$. #include<cstdio> #include<a ...

  3. BZOJ 2431 & DP

    题意:求逆序对数量为k的长度为n的排列的个数 SOL: 显然我们可以对最后一位数字进行讨论,判断其已经产生多少逆序对数量,然后对于前n-1位同样考虑---->每一个长度的排列我们都可以看做是相同 ...

  4. CSS:在IE浏览器下,元素下沉一行的解决办法

    HTML: <ul> <li><a href="">嘻嘻嘻嘻嘻嘻</a><span>2015-12-17</spa ...

  5. javascript继承机制的设计思想(ryf)

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

  6. Codeforces Round #371 (Div. 2) C

    传送门  map或者字典数的应用 简单题 题意: 思路: AC代码: #include<iostream> #include<cstring> #include<cmat ...

  7. [LintCode] Min Stack 最小栈

    Implement a stack with min() function, which will return the smallest number in the stack. It should ...

  8. npm link 安装本地模块,将本地模块cli化

    第三方学习地址 http://mp.weixin.qq.com/s?__biz=MzAxMTU0NTc4Nw==&mid=2661157390&idx=1&sn=6d96e54 ...

  9. Android课程---添加黑名单的练习2(课堂讲解)

    实现黑名单的添加.修改.查询和删除,首先得有封装的3个类,便于使用 BlackNumber.java package com.hanqi.test3; /** * Created by Adminis ...

  10. 骑士游历/knight tour - visual basic 解决

    在visual baisc 6 how to program 中文版第七章的练习题上看到了这个问题,骑士游历的问题. 在8x8的国际象棋的棋盘上,骑士(走法:一个方向走两格,另一个方向一格)不重复走完 ...