http://www.lydsy.com/JudgeOnline/problem.php?id=1095

查询最远点对,带修改

显然可以用动态点分治

对于每个点,维护两个堆

堆q1[x] 维护 点分树x的子树中,所有黑点到x的点分树中父节点的距离

堆q2[x]维护 点分树x的子节点的堆q1的堆顶,即若y是x在点分树中的子节点,则q2[x].push(q1[y].top())

再来维护一个全局的堆Q,维护所有q2的堆顶,即Q.push(q2[x].top())

  1. #include<cmath>
  2. #include<queue>
  3. #include<cstdio>
  4. #include<iostream>
  5.  
  6. using namespace std;
  7.  
  8. #define N 100001
  9.  
  10. #define Swap(a,b) ( (a)^=(b),(b)^=(a),(a)^=(b) )
  11.  
  12. int n;
  13.  
  14. int front[N],to[N<<],nxt[N<<],tot;
  15.  
  16. int fa[N];
  17.  
  18. bool light[N];
  19. int sum;
  20.  
  21. void read(int &x)
  22. {
  23. x=; char c=getchar();
  24. while(!isdigit(c)) c=getchar();
  25. while(isdigit(c)) { x=x*+c-''; c=getchar(); }
  26. }
  27.  
  28. void add(int u,int v)
  29. {
  30. to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
  31. to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
  32. }
  33.  
  34. namespace LCA
  35. {
  36. int fa[N][],dep[N],bin[],lim;
  37.  
  38. void dfs(int x)
  39. {
  40. for(int i=front[x];i;i=nxt[i])
  41. if(to[i]!=fa[x][])
  42. {
  43. dep[to[i]]=dep[x]+;
  44. fa[to[i]][]=x;
  45. dfs(to[i]);
  46. }
  47. }
  48.  
  49. int query(int x,int y)
  50. {
  51. if(dep[x]<dep[y]) swap(x,y);
  52. for(int i=lim;i>=;--i)
  53. if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
  54. if(x==y) return x;
  55. for(int i=lim;i>=;--i)
  56. if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
  57. return fa[x][];
  58. }
  59.  
  60. int dist(int x,int y)
  61. {
  62. return dep[x]+dep[y]-(dep[query(x,y)]<<);
  63. }
  64.  
  65. void main()
  66. {
  67. lim=log(n)/log();
  68. bin[]=;
  69. for(int i=;i<;++i) bin[i]=bin[i-]<<;
  70. dep[]=;
  71. dfs();
  72. for(int i=;i<=lim;++i)
  73. for(int j=;j<=n;++j)
  74. fa[j][i]=fa[fa[j][i-]][i-];
  75. }
  76. }
  77.  
  78. struct HEAP
  79. {
  80. priority_queue<int>heap,trash;
  81.  
  82. void Pop(int x) { trash.push(x); }
  83.  
  84. void Push(int x) { heap.push(x); }
  85.  
  86. int Size() { return heap.size()-trash.size(); }
  87.  
  88. int Top()
  89. {
  90. if(Size())
  91. {
  92. while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
  93. return heap.top();
  94. }
  95. return ;
  96. }
  97.  
  98. int Top_Sec()
  99. {
  100. if(Size()>=)
  101. {
  102. int first,second;
  103. while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
  104. first=heap.top(); heap.pop();
  105. while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
  106. second=heap.top(); heap.push(first);
  107. return first+second;
  108. }
  109. else return Top();
  110. }
  111.  
  112. }q1[N],q2[N],Q;
  113.  
  114. namespace Point_divide
  115. {
  116. int siz[N],mx[N];
  117. bool vis[N];
  118.  
  119. int root,min_size;
  120.  
  121. void get_dist(int x,int pa,int fa)
  122. {
  123. q1[root].Push(LCA::dist(pa,x));
  124. for(int i=front[x];i;i=nxt[i])
  125. if(to[i]!=fa && !vis[to[i]]) get_dist(to[i],pa,x);
  126. }
  127.  
  128. void get_size(int x,int fa)
  129. {
  130. siz[x]=; mx[x]=;
  131. for(int i=front[x];i;i=nxt[i])
  132. if(!vis[to[i]] && to[i]!=fa)
  133. {
  134. get_size(to[i],x);
  135. siz[x]+=siz[to[i]];
  136. if(siz[to[i]]>mx[x]) mx[x]=siz[to[i]];
  137. }
  138. }
  139.  
  140. void get_root(int x,int pa,int fa)
  141. {
  142. mx[x]=max(mx[x],siz[pa]-siz[x]);
  143. if(mx[x]<min_size) min_size=mx[x],root=x;
  144. for(int i=front[x];i;i=nxt[i])
  145. if(to[i]!=fa && !vis[to[i]]) get_root(to[i],pa,x);
  146. }
  147.  
  148. void work(int x,int pa)
  149. {
  150. min_size=n+;
  151. get_size(x,);
  152. get_root(x,x,);
  153. fa[root]=pa;
  154. vis[root]=true;
  155. q2[root].Push();
  156. q1[root].Push(LCA::dist(pa,root));
  157. for(int i=front[root];i;i=nxt[i])
  158. if(!vis[to[i]]) get_dist(to[i],pa,root);
  159. q2[pa].Push(q1[root].Top());
  160. int rt=root;
  161. for(int i=front[root];i;i=nxt[i])
  162. if(!vis[to[i]]) work(to[i],rt);
  163. if(q2[rt].Size()>=) Q.Push(q2[rt].Top_Sec());
  164. }
  165.  
  166. void main()
  167. {
  168. work(,);
  169. }
  170.  
  171. }
  172.  
  173. void turn_off(int x)
  174. {
  175. if(q2[x].Size()>=) Q.Pop(q2[x].Top_Sec());
  176. q2[x].Push();
  177. if(q2[x].Size()>=) Q.Push(q2[x].Top_Sec());
  178. for(int u=x;fa[u];u=fa[u])
  179. {
  180. if(q2[fa[u]].Size()>=) Q.Pop(q2[fa[u]].Top_Sec());
  181. if(q1[u].Size()) q2[fa[u]].Pop(q1[u].Top());
  182. q1[u].Push(LCA::dist(fa[u],x));
  183. q2[fa[u]].Push(q1[u].Top());
  184. if(q2[fa[u]].Size()>=) Q.Push(q2[fa[u]].Top_Sec());
  185. }
  186. }
  187.  
  188. void turn_on(int x)
  189. {
  190. if(q2[x].Size()>=) Q.Pop(q2[x].Top_Sec());
  191. q2[x].Pop();
  192. if(q2[x].Size()>=) Q.Push(q2[x].Top_Sec());
  193. for(int u=x;fa[u];u=fa[u])
  194. {
  195. if(q2[fa[u]].Size()>=) Q.Pop(q2[fa[u]].Top_Sec());
  196. q2[fa[u]].Pop(q1[u].Top());
  197. q1[u].Pop(LCA::dist(x,fa[u]));
  198. if(q1[u].Size()) q2[fa[u]].Push(q1[u].Top());
  199. if(q2[fa[u]].Size()>=) Q.Push(q2[fa[u]].Top_Sec());
  200. }
  201. }
  202.  
  203. int main()
  204. {
  205. //freopen("hide.in","r",stdin);
  206. //freopen("hide.out","w",stdout);
  207. read(n);
  208. int u,v;
  209. for(int i=;i<n;++i)
  210. {
  211. read(u); read(v);
  212. add(u,v);
  213. }
  214. LCA::main();
  215. Point_divide::main();
  216. sum=n;
  217. int m; char s[];
  218. read(m);
  219. // printf("%d\n",Q.Top());
  220. while(m--)
  221. {
  222. scanf("%s",s);
  223. if(s[]=='G')
  224. {
  225. if(sum>=) printf("%d\n",Q.Top());
  226. else printf("%d\n",sum-);
  227. }
  228. else
  229. {
  230. read(u);
  231. if(light[u])turn_off(u),sum++;
  232. else turn_on(u),sum--;
  233. light[u]^=;
  234. //printf("%d\n",Q.Top());
  235. }
  236. }
  237. return ;
  238. }

bzoj千题计划245: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. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  4. bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGo ...

  5. bzoj千题计划163:bzoj1060: [ZJOI2007]时态同步

    http://www.lydsy.com/JudgeOnline/problem.php?id=1060 以激发器所在节点为根 终止节点一定是叶节点 记录点的子树内最深的终止节点 然后从根往下使用道具 ...

  6. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  7. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  8. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  9. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

随机推荐

  1. 洛谷P4003 无限之环(infinityloop)(网络流,费用流)

    洛谷题目传送门 题目 题目描述 曾经有一款流行的游戏,叫做 Infinity Loop,先来简单的介绍一下这个游戏: 游戏在一个 n ∗ m 的网格状棋盘上进行,其中有些小方格中会有水管,水管可能在格 ...

  2. [SCOI2010]股票交易

    题目大意: 网址:https://www.luogu.org/problemnew/show/P2569 大意:在接下来的T天中,每天股票有一个买入价格Api与卖出价格Bpi. 同时,每天买入股票数与 ...

  3. 【Android】[Problem]-"Waiting for target device to come online".

    环境: win10专业版(创意者),Android studio 2.3.1 问题描述: 安装玩Android studio之后创建一个项目,建立AVD之后,运行程序时一直不能启动AVD,具体描述为: ...

  4. 小程序input输入框获取焦点时,文字会出现闪动

    最近在开发小程序时,发现一个有趣的现象.input里面设置了placeholder,随后当输入框获取焦点时,文字会出现一瞬间的抖动,随后正常. 猜想可能是设置的font-family不同引起的抖动,但 ...

  5. c# winform中的一段代码赏析

    我遇到了一个bug,是客户测试我们的产品,报出来的,而且有异常信息文件,这对于定位问题,很有帮助. 我找到源码看了下,bug还无法重现.于是我随便点点客户端,经过了几次调试,结果报出错误来了.客户端界 ...

  6. Windows Live Writer介绍及相关问题解决

    今天本来想说更新一篇我的文章,更新的过程中添加了很多的内容,里面的图片太多了,导致我浏览器占用的内存不断增大,浏览器变得很卡,最后过了好久我终于更新完文章打算保存的时候居然卡住,然后所有我更新的文字和 ...

  7. Spark Streaming高级特性在NDCG计算实践

    从storm到spark streaming,再到flink,流式计算得到长足发展, 依托于spark平台的spark streaming走出了一条自己的路,其借鉴了spark批处理架构,通过批处理方 ...

  8. windows下安装Virtualenvwrapper

    windows下安装Virtualenvwrapper 我们可以使用Virtualenvwrapper来方便地管理python虚拟环境,但是在windows上安装的时候.....直接 install  ...

  9. struts2和spring mvc的区别

    在项目中使用struts2和spring mvc为了实现后台的业务代码和前台数据之间的传递,现在基本上不会有用struts2的了,几次面试问的最多的关于struts2的问题就是struts2和spri ...

  10. JavaSE中常见的工具类

    Arrays 用来操作数组, 常用方法是 sort()和toString()方法 Iterator 我们常说的迭代器就是这哥们,专门用来操作集合元素的工具类 常用方法是: hasNex()t和next ...