题目


分析

考虑建一棵虚树,倍增找到虚树上相邻两个点的中间点统计答案

记录每个虚树点最近的距离以及编号最小的点,主要是细节问题


代码

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. #define rr register
  5. using namespace std;
  6. const int N=300011; struct node{int y,next;}e[N<<1],E[N];
  7. int dep[N],siz[N],v[N],dfn[N],tot,f[N][19],a[N],lg[N],stac[N];
  8. int low[N],dp[N],W[N],b[N],n,m,et=1,Et,ans[N],as[N],hs[N],mm;
  9. inline signed iut(){
  10. rr int ans=0; rr char c=getchar();
  11. while (!isdigit(c)) c=getchar();
  12. while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
  13. return ans;
  14. }
  15. inline void print(int ans){
  16. if (ans>9) print(ans/10);
  17. putchar(ans%10+48);
  18. }
  19. inline void dfs(int x,int fa){
  20. dep[x]=dep[fa]+1,siz[x]=1,dfn[x]=++tot,f[x][0]=fa;
  21. for (rr int i=0;f[x][i];++i) f[x][i+1]=f[f[x][i]][i];
  22. for (rr int i=as[x];i;i=e[i].next)
  23. if (e[i].y!=fa) dfs(e[i].y,x),siz[x]+=siz[e[i].y];
  24. }
  25. inline signed lca(int x,int y){
  26. if (dep[x]<dep[y]) x^=y,y^=x,x^=y;
  27. for (rr int i=lg[dep[x]];~i;--i)
  28. if (dep[f[x][i]]>=dep[y]) x=f[x][i];
  29. if (x==y) return x;
  30. for (rr int i=lg[dep[x]];~i;--i)
  31. if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
  32. return f[x][0];
  33. }
  34. inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
  35. inline void add(int x,int y){E[++Et]=(node){y,hs[x]},W[Et]=dep[y]-dep[x],hs[x]=Et;}
  36. inline void Insert(int x){
  37. if (!tot) {stac[++tot]=x; return;}
  38. rr int Lca=lca(x,stac[tot]);
  39. while (tot>1&&dep[Lca]<dep[stac[tot-1]]) add(stac[tot-1],stac[tot]),--tot;
  40. if (dep[Lca]<dep[stac[tot]]) add(Lca,stac[tot]),--tot;
  41. if (stac[tot]!=Lca) stac[++tot]=Lca; stac[++tot]=x;
  42. }
  43. inline void dfs1(int x,int fa){
  44. dp[x]=1e7;
  45. for (rr int i=hs[x];i;i=E[i].next)
  46. if (E[i].y!=fa){
  47. dfs1(E[i].y,x);
  48. if (dp[E[i].y]+W[i]<dp[x]) dp[x]=dp[E[i].y]+W[i],low[x]=low[E[i].y];
  49. else if (dp[E[i].y]+W[i]==dp[x]&&low[x]>low[E[i].y]) low[x]=low[E[i].y];
  50. }
  51. if (v[x]) dp[x]=0,low[x]=x;
  52. }
  53. inline void answ(int x,int fa){
  54. rr int x1=x,x2=x;
  55. for (rr int i=lg[dep[x1]];~i;--i)
  56. if (dep[f[x1][i]]>dep[fa]) x1=f[x1][i];
  57. ans[low[fa]]-=siz[x1];//先把可能影响的点删除
  58. for (rr int i=lg[dep[x2]];~i;--i){
  59. rr int Bot=dep[x]-dep[f[x2][i]]+dp[x],Top=dep[f[x2][i]]-dep[fa]+dp[fa];
  60. if (dep[f[x2][i]]>dep[fa]&&(Bot<Top||(Bot==Top&&low[x]<low[fa]))) x2=f[x2][i];
  61. }
  62. ans[low[fa]]+=siz[x1]-siz[x2],ans[low[x]]+=siz[x2]-siz[x];//用中间点分开统计贡献
  63. }
  64. inline void dfs2(int x,int fa){
  65. for (rr int i=hs[x];i;i=E[i].next)
  66. if (E[i].y!=fa){
  67. if (dp[x]+W[i]<dp[E[i].y]) dp[E[i].y]=dp[x]+W[i],low[E[i].y]=low[x];
  68. else if (dp[x]+W[i]==dp[E[i].y]&&low[E[i].y]>low[x]) low[E[i].y]=low[x];
  69. answ(E[i].y,x),dfs2(E[i].y,x);
  70. }
  71. ans[low[x]]+=siz[x],hs[x]=0;//补回未加入的点
  72. }
  73. signed main(){
  74. n=iut(),lg[0]=-1;
  75. for (rr int i=1;i<=n;++i) lg[i]=lg[i>>1]+1;
  76. for (rr int i=1;i<n;++i){
  77. rr int x=iut(),y=iut();
  78. e[++et]=(node){y,as[x]},as[x]=et;
  79. e[++et]=(node){x,as[y]},as[y]=et;
  80. }
  81. dfs(1,0);
  82. for (rr int Q=iut();Q;--Q){
  83. mm=m=iut(),tot=Et=0,a[++m]=1;
  84. for (rr int i=1;i<m;++i) v[b[i]=a[i]=iut()]=1;
  85. sort(a+1,a+1+m,cmp),m=unique(a+1,a+1+m)-a-1;
  86. for (rr int i=1;i<=m;++i) Insert(a[i]);
  87. for (;tot>1;--tot) add(stac[tot-1],stac[tot]);
  88. dfs1(1,0),dfs2(1,0);
  89. for (rr int i=1;i<=mm;++i) if (b[i])
  90. print(ans[b[i]]),putchar(i==mm?10:32),ans[b[i]]=0;
  91. for (rr int i=1;i<=m;++i) v[a[i]]=0;
  92. }
  93. return 0;
  94. }

#虚树,树形dp#洛谷 3233 [HNOI2014]世界树的更多相关文章

  1. 【BZOJ-3572】世界树 虚树 + 树形DP

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

  2. 【BZOJ-2286】消耗战 虚树 + 树形DP

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2120  Solved: 752[Submit][Status] ...

  3. bzoj 2286(虚树+树形dp) 虚树模板

    树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5002  Sol ...

  4. BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca

    BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...

  5. 洛谷 P3233 [HNOI2014]世界树(虚树+dp)

    题面 luogu 题解 数据范围已经告诉我们是虚树了,考虑如何在虚树上面\(dp\) 以下摘自hzwer博客: 构建虚树以后两遍dp处理出虚树上每个点最近的议事处 然后枚举虚树上每一条边,考虑其对两端 ...

  6. 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)

    传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...

  7. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  8. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  9. ●洛谷P3233 [HNOI2014]世界树

    题链: https://www.luogu.org/problemnew/show/P3233题解: 虚树,dp,倍增. 首先对于每个询问,要把虚树建出来,这一步就从略了.这里着重分享一下如何求答案. ...

  10. 洛谷3233 HNOI2014(虚树+dp)

    膜拜一发\(mts\_246,forever\_shi\) 这两位爷是真的无敌! 首先来看这个题,一看题目的数据范围和"关键点"字眼,我们就能得知这是一道虚树题 那就先一如既往的建 ...

随机推荐

  1. Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试

    前言   上一篇使用QtWebApp的基于Qt的轻量级http服务器实现了一个静态网页返回的Demo,网页服务器很重要的就是日志,因为在服务器类上并没有直接返回,所以,本篇先把日志加上.   Demo ...

  2. python中的泛型使用TypeVar

    引入为什么需要TypeVar PEP484的作者希望借助typing模块引入类型提示,不改动语言的其它部分.通过精巧的元编程技术,让类 支持[]运算不成问题.但是方括号内的T变量必须在某处定义,否则要 ...

  3. isort包

    记录 为什么会使用到这个包,原因是之前在本地开发的时候,导包的时候可能由于不规范,其实你自己看着挺规范的,但是呢后续组长进行打包的时候,代码出现了不规范的情况,导致打包失败.原因就是导包不规范造成的. ...

  4. 【LeetCode二叉树#04】判断对称二叉树、相同的树、另一棵子树、树的子结构(二叉树相等判断)

    对称二叉树 力扣题目链接(opens new window) 给定一个二叉树,检查它是否是镜像对称的. 思路 本题中,不能单纯去比较左右子节点的是否对称(都有值且不为空) 因为如果按上面那样做的话,到 ...

  5. Redis哨兵(sentinel)

    目录 前言 原理 架构图 下载 命令 配置 启动 查看 Sentinel(哨兵)配置 常用命令 Q&A Redis主从配置异常解决:Error condition on socket for ...

  6. Unity3D之OnTriggerEnter和OnCollisionEnter

    OnCollisionEnter方法要求碰撞的发起方必须拥有刚体,而被碰撞方有没有刚体并不重要; OnTriggerEnter方法则对此没有要求,只需要碰撞双方有一个具有刚体即可触发,当有物体勾选is ...

  7. Android drawable与mipmap的区别(android资源文件放置位置)

    1.Drawable Android 把可绘制的对象抽象为Drawable,不同的图形图像代表着不同的darwable类型, 通常我们在代码中不会直接接触drawable实现类的,是由android ...

  8. Java-- Arrays操纵数组的工具类

    1 //操作数组的工具类 java.util.Arrays :操作数组的工具类 里面定义了很多操作数组的方法 2 public static void main(String[] args) 3 { ...

  9. linux压缩文件并排除指定目录

    今天要在linux上打包一个项目另作他用,但是项目图片都是放本地服务器的,整个项目打包好后有2G多下载十分费时.项目中的图片我们可以不要,所以压缩的时候要排除图片目录. 具体命令如下: // 参数说明 ...

  10. 继续总结Python中那些简单好用的用法

    上一篇文章Python中那些简单又好用的特性和用法发出后,群里的小伙伴又给补充了几个好用的用法,结合生产实用经验汇总整理如下,各位看官如有需要请自取 反射,反射是一种机制,可以在运行时获取.检查和修改 ...