题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3572


算是细节题了吧。。

  构出虚树,考虑z正反DP两次求出虚树中每个点最近的议事处是哪一个点,然后枚举虚树中的每一条边${X->Y}$,对于两点间在原树中的路径,显然存在一个分界点使得自分界点之上的所有点归最靠近$X$的议事处管辖,之下的点归最靠经$Y$的议事处管辖,还有一些没有考虑过的点,另外统计一下即可。


  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<cstdlib>
  6. #include<cmath>
  7. #include<cstring>
  8. using namespace std;
  9. #define maxn 310000
  10. #define llg long long
  11. #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
  12. llg n,m,f[maxn][],deep[maxn],dfn[maxn],cnt,size[maxn],s[maxn],top;
  13. llg a[maxn],b[maxn],bel[maxn],c[maxn],rem[maxn],ans[maxn];
  14.  
  15. vector<llg>g[maxn];
  16.  
  17. bool cmp(llg x,llg y) {return dfn[x]<dfn[y];}
  18.  
  19. void link(llg x,llg y){g[x].push_back(y);}
  20.  
  21. void dfs(llg x,llg fa)
  22. {
  23. dfn[x]=++cnt;
  24. llg w=g[x].size(),v;
  25. size[x]=;
  26. for (llg i=;i<w;i++)
  27. {
  28. v=g[x][i];
  29. if (v==fa) continue;
  30. deep[v]=deep[x]+;
  31. f[v][]=x;
  32. dfs(v,x);
  33. size[x]+=size[v];
  34. }
  35. }
  36.  
  37. void make_f()
  38. {
  39. for (llg j=;j<=;j++)
  40. for (llg i=;i<=n;i++)
  41. f[i][j]=f[f[i][j-]][j-];
  42. }
  43.  
  44. llg lca(llg x,llg y)
  45. {
  46. if (deep[x]<deep[y]) swap(x,y);
  47. for (llg i=;i>=;i--)
  48. if (deep[f[x][i]]>=deep[y])
  49. x=f[x][i];
  50. if (x==y) return x;
  51. for (llg i=;i>=;i--)
  52. if (f[x][i]!=f[y][i])
  53. {
  54. x=f[x][i];
  55. y=f[y][i];
  56. }
  57. return f[x][];
  58. }
  59.  
  60. llg dis(llg x,llg y) {return deep[x]+deep[y]-*deep[lca(x,y)];}
  61.  
  62. void init()
  63. {
  64. cin>>n;
  65. llg x,y;
  66. for (llg i=;i<n;i++)
  67. {
  68. scanf("%lld%lld",&x,&y);
  69. g[x].push_back(y),g[y].push_back(x);
  70. }
  71. deep[]=;
  72. dfs(,-);
  73. make_f();
  74. }
  75.  
  76. void build_tree()
  77. {
  78. cnt=top=;
  79. sort(a+,a+m+,cmp);
  80. if (bel[]!=) s[++top]=;
  81. for (llg i=;i<=m;i++)
  82. {
  83. llg x=a[i],fa=;
  84. while (top)
  85. {
  86. fa=lca(s[top],x);
  87. if (top> && deep[fa]<deep[s[top-]])
  88. {
  89. link(s[top-],s[top]);
  90. top--;
  91. }
  92. else
  93. if (deep[fa]<deep[s[top]]){ link(fa,s[top--]); break;}
  94. else
  95. break;
  96.  
  97. }
  98. if (s[top]!=fa) s[++top]=fa;
  99. s[++top]=x;
  100. }
  101. while (--top) link(s[top],s[top+]);
  102. }
  103.  
  104. void dfs1(llg x,llg fa)
  105. {
  106. c[++cnt]=x;
  107. rem[x]=size[x];
  108. llg w=g[x].size(),v;
  109. for (llg i=;i<w;i++)
  110. {
  111. v=g[x][i];
  112. dfs1(v,x);
  113. if (v==fa) continue;
  114. if (!bel[v]) continue;//why
  115. llg d1=dis(bel[v],x),d2=dis(bel[x],x);
  116. if ((d1==d2 && bel[v]<bel[x]) || (d1<d2) || !bel[x]) bel[x]=bel[v];
  117. }
  118. }
  119.  
  120. void dfs2(llg x,llg fa)
  121. {
  122. llg w=g[x].size(),v;
  123. for (llg i=;i<w;i++)
  124. {
  125. v=g[x][i];
  126. if (v==fa) continue;
  127. llg d1=dis(bel[x],v),d2=dis(bel[v],v);
  128. if ((d1==d2 && bel[v]>bel[x]) || (d1<d2) || !bel[v])
  129. bel[v]=bel[x];
  130. dfs2(v,x);
  131. }
  132. }
  133.  
  134. void work(llg x,llg y)
  135. {
  136. llg son=y,mid=y;
  137. for (llg i=;i>=;i--)
  138. if (deep[f[son][i]]>deep[x]) son=f[son][i];
  139. rem[x]-=size[son];
  140. if (bel[x]==bel[y]) {ans[bel[x]]+=size[son]-size[y]; return;}
  141. for (llg i=;i>=;i--)
  142. {
  143. llg ne=f[mid][i];
  144. if (deep[ne]<=deep[x]) continue;
  145. llg d1=dis(bel[x],ne),d2=dis(bel[y],ne);
  146. if (d1>d2 || (d1==d2 && bel[y]<bel[x])) mid=ne;
  147. }
  148. ans[bel[x]]+=size[son]-size[mid];
  149. ans[bel[y]]+=size[mid]-size[y];
  150. }
  151.  
  152. int main()
  153. {
  154. yyj("tree");
  155. init();
  156. llg T; cin>>T;
  157. for (llg i=;i<=n;i++)
  158. {
  159. while (!g[i].empty()) g[i].pop_back();
  160. //std::vector(c).swap(vec);
  161. }
  162. while (T--)
  163. {
  164. scanf("%lld",&m);
  165. for (llg i=;i<=m;i++)
  166. {
  167. scanf("%lld",&a[i]);
  168. b[i]=a[i]; bel[a[i]]=a[i];
  169. }
  170. build_tree();
  171. dfs1(,-); dfs2(,-);
  172. for (llg i=;i<=cnt;i++)
  173. {
  174. llg w=g[c[i]].size();
  175. llg la=-;
  176. for (llg j=;j<w;j++)
  177. {
  178. if (g[c[i]][j]==la) continue;
  179. la=g[c[i]][j];
  180. work(c[i],g[c[i]][j]);
  181. }
  182. }
  183. for (llg i=;i<=cnt;i++) ans[bel[c[i]]]+=rem[c[i]];
  184. for (llg i=;i<=m;i++) printf("%lld ",ans[b[i]]);
  185. printf("\n");
  186. for (llg i=;i<=cnt;i++)
  187. {
  188. ans[c[i]]=bel[c[i]]=rem[c[i]]=;
  189. while (!g[c[i]].empty()) g[c[i]].pop_back();
  190. }
  191. }
  192. return ;
  193. }

【BZOJ】3572: [Hnoi2014]世界树的更多相关文章

  1. BZOJ 3572: [Hnoi2014]世界树

    BZOJ 3572: [Hnoi2014]世界树 标签(空格分隔): OI-BZOJ OI-虚数 OI-树形dp OI-倍增 Time Limit: 20 Sec Memory Limit: 512 ...

  2. bzoj 3572: [Hnoi2014]世界树 虚树 && AC500

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 520  Solved: 300[Submit][Status] ...

  3. bzoj 3572 [Hnoi2014]世界树(虚树+DP)

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 645  Solved: 362[Submit][Status] ...

  4. bzoj 3572 [Hnoi2014]世界树——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3572 关于虚树:https://www.cnblogs.com/zzqsblog/p/556 ...

  5. BZOJ 3572: [Hnoi2014]世界树 虚树 树形dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=3572 http://hzwer.com/6804.html 写的时候参考了hzwer的代码,不会写 ...

  6. bzoj 3572: [Hnoi2014]世界树 虚树

    题目: Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生 ...

  7. BZOJ 3572 [HNOI2014]世界树 (虚树+DP)

    题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...

  8. BZOJ 3572: [Hnoi2014]世界树 [虚树 DP 倍增]

    传送门 题意: 一棵树,多次询问,给出$m$个点,求有几个点到给定点最近 写了一晚上... 当然要建虚树了,但是怎么$DP$啊 大爷题解传送门 我们先求出到虚树上某个点最近的关键点 然后枚举所有的边$ ...

  9. 【BZOJ】3572: [Hnoi2014]世界树 虚树+倍增

    [题意]给定n个点的树,m次询问,每次给定ki个特殊点,一个点会被最近的特殊点控制,询问每个特殊点控制多少点.n,m,Σki<=300000. [算法]虚树+倍增 [题解]★参考:thy_asd ...

随机推荐

  1. Java技术学习路线笔记:Maven安装和作用

    Maven是一个基于项目对象模型(POM)的概念的纯java开发的开源的项目管理工具.主要用来管理java项目,进行依赖管理(jar包管理,能自动分析项目所需的依赖软件包,并到Maven仓库区下载)和 ...

  2. vue 组件之间 的通信

      组件之间通信: 同级组件之间通信:两个组件定义应用到同一个vue实例之下: <div id="webapp" class="box">    & ...

  3. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:

    ### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You h ...

  4. logstash 5.1.1 学习

    Logstash 5.1.1 安装配置 安装和配置 java 环境: [root@ ~]# tar xf jdk-8u71-linux-x64.tar.gz [root@ ~]# mv jdk1.8. ...

  5. Docker学习笔记之docker volume 容器卷的那些事(一)

    预览目录 volume 方式 相关用例 使用方式 使用 volume driver bind mount 方式 相关用例 使用方式 配置selinux标签 配置macOS的安装一致性 tmpfs 方式 ...

  6. win7搭建pyqt4开发环境

    版本 win7 64bit python2.7 https://www.python.org/ftp/python/2.7.13/python-2.7.13.amd64.msi pyqt4 https ...

  7. 一次 Java 内存泄漏排查过程,涨姿势

    人人都会犯错,但一些错误是如此的荒谬,我想不通怎么会有人犯这种错误.更没想到的是,这种事竟发生在了我们身上.当然,这种东西只有事后才能发现真相.接下来,我将讲述一系列最近在我们一个应用上犯过的这种错误 ...

  8. 如何搭建一个 MySQL 分布式集群

    1.准备集群搭建环境 使用6台虚拟机来搭建 MySQL分布式集群 ,相应的实验环境与对应的MySQL节点之间的对应关系如下图所示: 管理节点(MGM):这类节点的作用是管理MySQLCluster内的 ...

  9. JavaBean的getters和setters方法自动生成

    xgClass.java文件: public class XgClass { private String ccCityDerate1000Num; } 添加getter/setter方法: 在代码区 ...

  10. Stanford CS231n实践笔记(课时22卷积神经网络工程实践技巧与注意点 cnn in practise 上)

    本课主要2个实践内容: 1.keras中数据集丰富,从数据集中提取更多特征(Data augmentation) 2.迁移学习(Tranform learning) 代码:https://github ...