这个题有Σ的条件,肯定还是用log结构求询问点相关了

但这个题是点之间的距离关系,所以本来想用中点来代替原来的lca,但中点的个数不满足任何单调性,而且个数也不是n个

所以还是要用lca,所以考虑lca和中点的关系,lca的好处就是n个点对之间只有最多n个lca

这时就需要一定的转化,把原来的确定中点问题变成确定 最少影响点 问题

因为如果把所有拐点表示出来,剩下的就都是线段了

自然容易想到讨论lca的归属和距离。 能知道,对于一个点,可能会属于下面的点,也可能会属于上面的点

向上更新的方向是不一定的,因为更新后的点有可能会更新下面的点

但更新到最优解后的向下方向是单一的,即上面的点更新了下面的点,那这个最优值只能向下更新,向上更新没有意义(向上的路是唯一的)

所以就类似树形dp的思路,先统计向上的最优值,然后再考虑向下的更新,可解决所有点的归属和最近距离

然后这些点就把树分离成了若干区间,需要把最近两点间的路径分成两部分

需要分类讨论,由于有距离影响和序号大小影响,待划分的区间可能靠深度大的点,也可能靠着深度小的点,

分成点的距离、区间的长度进行讨论

这个题还是把虚树建出来好写一点,但区间划分是这个题最繁琐的地方

码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 600005
int cnt,ans[N],s,sta[N],x,y,dfn[N],sz[N],er[30],minn[N],id[N],xia[N],hou[N],zhong[N],d[N],tot,n,m,i,j,f[N],fu[N][25],lin[N],daan[N];
vector<int>v[N];
void dfs(int o,int dis)
{dfn[o]=++cnt;d[o]=dis;sz[o]=1;int i,nd;   for(i=0;i<v[o].size();i++){nd=v[o][i];   if(nd==fu[o][0])continue;fu[nd][0]=o;for(j=1;j<=20;j++)fu[nd][j]=fu[fu[nd][j-1]][j-1];dfs(nd,dis+1);sz[o]+=sz[nd];}
}
int getlca(int x,int y)
{int i,j;
if(d[x]<d[y])swap(x,y);
int cj=d[x]-d[y];for(i=20;i>=0;i--)if(er[i]&cj)x=fu[x][i];if(x==y)return x;for(i=20;i>=0;i--){if(fu[x][i]!=fu[y][i])x=fu[x][i],y=fu[y][i]; }   return fu[x][0];
}
bool cmp(int a,int b)
{return dfn[a]<dfn[b];
}
void jia(int a,int b)
{hou[++tot]=xia[a],xia[a]=tot,zhong[tot]=b;
}
void dp1(int o)
{int i,nd;for(i=xia[o];i!=-1;i=hou[i]){nd=zhong[i];dp1(nd);if(minn[o]>minn[nd]+d[nd]-d[o]||(minn[o]==minn[nd]+d[nd]-d[o]&&id[o]>id[nd])){minn[o]=minn[nd]+d[nd]-d[o];id[o]=id[nd];}}
}
void dp2(int o)
{int i,nd;for(i=xia[o];i!=-1;i=hou[i]){nd=zhong[i];if(minn[nd]>minn[o]+d[nd]-d[o]||(minn[nd]==minn[o]+d[nd]-d[o]&&id[nd]>id[o]))minn[nd]=minn[o]+d[nd]-d[o],id[nd]=id[o];dp2(nd);}
}
int zhao(int o,int jl)
{for(i=0;i<=20;i++)if(jl&er[i])o=fu[o][i];return o;
}
void dp3(int o)
{int i,nd;ans[o]=sz[o];for(i=xia[o];i!=-1;i=hou[i]){nd=zhong[i];dp3(nd);int jl,xx,sx,mb;           if(minn[o]>minn[nd]){xx=(minn[o]-minn[nd])+1;sx=d[nd]-d[o]-1;jl=sx-xx+1;if(jl<=0){mb=zhao(nd,d[nd]-d[o]-1);ans[o]-=sz[mb];ans[nd]+=sz[mb]-sz[nd];           }elseif(jl&1){mb=zhao(nd,(sx+xx-1)/2);if(id[o]>id[nd])mb=fu[mb][0];ans[nd]+=sz[mb]-sz[nd];ans[o]-=sz[mb];  }else{mb=zhao(nd,(sx+xx)/2);ans[nd]+=sz[mb]-sz[nd];ans[o]-=sz[mb];             }}else{jl=d[nd]-d[o]-1- (minn[nd]-minn[o]);if(jl<=0){ans[o]-=sz[nd];}else{mb=zhao(nd,jl/2);if(jl&1){if(id[o]>id[nd]) mb=fu[mb][0];ans[o]-=sz[mb];ans[nd]+=sz[mb]-sz[nd];}else{ans[o]-=sz[mb];ans[nd]+=sz[mb]-sz[nd];}}}}
}
void dp4(int o)
{int i,nd;daan[id[o]]+=ans[o];for(i=xia[o];i!=-1;i=hou[i]){nd=zhong[i];       dp4(nd);}   xia[o]=-1;minn[o]=9999999;
}
void work()
{tot=0;for(i=1;i<=s;i++)minn[f[i]]=0,id[f[i]]=f[i];sort(f+1,f+1+s,cmp);int top=0;f[++s]=1;sta[0]=1;sta[++top]=f[1];for(i=2;i<=s;i++){   int lca=getlca(f[i-1],f[i]);while(d[lca]<d[sta[top]]&&top){if(d[lca]<d[sta[top-1]]){jia(sta[top-1],sta[top]);}else { jia(lca,sta[top]);}top--;       }               if(sta[top]!=lca)sta[++top]=lca;    if(sta[top]!=f[i])sta[++top]=f[i];}dp1(1);dp2(1);dp3(1);dp4(1);
}
int main()
{
memset(xia,-1,sizeof(xia));er[0]=1;for(i=1;i<=20;i++)er[i]=er[i-1]*2;scanf("%d",&n);for(i=1;i<=n;i++)minn[i]=9999999;for(i=1;i<n;i++){ scanf("%d%d",&x,&y);v[x].push_back(y);v[y].push_back(x);  }scanf("%d",&m);dfs(1,0);for(j=1;j<=m;j++){scanf("%d",&s);for(i=1;i<=s;i++){scanf("%d",&lin[i]);f[i]=lin[i];                           }work();    s--;for(i=1;i<=s;i++)printf("%d ",daan[lin[i]]),daan[lin[i]]=0;printf("\n");    }
}

bzoj3572 [HNOI2014]世界树 虚树 +乱dp相关推荐

  1. [HNOI2014]世界树 (虚树DP+倍增)

    世界树 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石 ...

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

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

  3. BZOJ3572 [Hnoi2014]世界树 【虚树 + 树形dp】

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

  4. 「HNOI2014」世界树 虚树

    「HNOI2014」世界树 前置技能:虚树. (本题可以通过以下相似的思想用线段树维护子树信息和倍增找中点完成,代码短很多,但本篇题解不涉及) 题解部分 这种总询问点数不大,但是询问次数多,可以想到用 ...

  5. bzoj3572世界树 虚树+树型动规

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 1786   Solved: 957 [ Submit][ ...

  6. BZOJ3572: [Hnoi2014]世界树

    题解: 首先建出一颗虚树  对于虚树上的每个节点DP找出离得最近的关键节点的编号和距离 然后考虑一遍dfs 对于每条链上子树 我们倍增找到mid位置 然后mid以下的属于下面节点 mid以上的属于上面 ...

  7. [bzoj3572][HNOI2014]世界树

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

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

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

  9. luogu3233 世界树 (虚树)

    反正肯定要建虚树,考虑建完之后怎么做 先随便dp一下算出来距离某点最近的询问点mi[x](因为有的虚树上的点它不是询问点嘛) 那我们对于某条链x到fa[x]上的非虚树上的点(包括他们的非虚树上的孩子) ...

最新文章

  1. 常用排序算法对比(时间复杂度、稳定性)
  2. hibernate的native sql查询
  3. HikariCP为什么自己造了一个FastList?
  4. 从零开始学python微课视频版-从零开始学Python(微课视频版)
  5. 心疼啊今天在四季青买衣服的时候在试衣服的时候,竟然有个小偷把我的n73手机给偷去了,...
  6. 使用SLIN事务码进行ABAP程序扩展语法检查
  7. (花里胡哨)New Game!(牛客国庆集训派对Day1)
  8. 弄断过河电缆_你说的是:剪断电缆线
  9. python random模块导入_Python学习笔记(二十)—模块的导入
  10. java range注解_最全的Java Spring注解
  11. (最完美)MIUI12系统的Usb调试模式在哪里开启的步骤
  12. SQLI-LABS——Page-2 Advanced Injections Less21~Less37
  13. 怎么在计算机网络上添加文件,教你win7如何设置网络共享文件夹
  14. 关于人工智能写作的发展以及看法
  15. js汉字转拼音包——pinyin-pro
  16. Windows系统中如何将C盘划分为多个盘符的详细图文教程
  17. 【flask入门系列】请求钩子与上下文
  18. 将SQL Server表导出为txt文件
  19. 在wps上使用Endnote
  20. php生成复杂url,php – 生成SEO友好URL(slugs)

热门文章

  1. Android事件分发 笔记
  2. Error-backpropagation in temporally encoded networks of spiking neurons 误差传播在时间编码的脉冲神经网络
  3. R语言学习笔记(七)方差分析
  4. C++学习系列笔记(五)
  5. python 函数 过程_python之函数篇
  6. 两个线程能在cpu中同时运行吗_多核和多线程那些事
  7. python制作的游戏如何转化为swf_如何从python生成swf格式的幻灯片?
  8. linux nginx编译详解,Linux下nginx编译安装教程和编译参数详解
  9. matlab音频信号的采样与重构,信号与系统实验(MATLAB 西电版)实验21 综合实验2-音频信号的采样与重构.ppt...
  10. mysql mpm_使用Zabbix + MPM全面监控MySQL