【HNOI2014】世界树(worldtree)

(File IO): input:worldtree.in output:worldtree.out
Time Limits: 2000 ms Memory Limits: 524288 KB

Description

Input

Output

Sample Input

10
2 1
3 2
4 3
5 4
6 1
7 3
8 3
9 4
10 1
5
2
6 1
5
2 7 3 6 9
1
8
4
8 7 10 3
5
2 9 3 5 8

Sample Output

1 9
3 1 4 1 1
10
1 1 3 5
4 1 3 1 1

Data Constraint

Hint


Solution

一眼看上去——不会。。。
果断上暴力。。。

其实,观察到∑m[i]<=3∗105∑m[i]<=3∗105\sum m[i]可以考虑建立虚树。
虚树是什么?
根据需要,保留有用的点,点与点之间的当成一条边,并且要保留数的形状,也就是lca要保留。
lca?
两两的一共12n(n−1)12n(n−1)\frac 12n(n-1)个??但,事实上,不同的lca顶多n-1个。
因为:

  • 对于点对(x,y,z):lca(x,z)一定是lca(x,y)和lca(y,z)中的一个

设lca(x,y)=a,lca(y,z)=b,lca(x,z)=clca(x,y)=a,lca(y,z)=b,lca(x,z)=clca(x,y)=a,lca(y,z)=b,lca(x,z)=c
∵∵\because a为y的祖先,b为y的祖先,∴∴\thereforea,b,y在一条路径上
假设deepa<deepbdeepa<deepbdeep_a,那么a为b的祖先,同时a为y,z的某一公共祖先
∴∴\thereforea为x,y,z的某一公共祖先
若a并不是最近的祖先,则∃d|d∈tree(a)∃d|d∈tree(a)\exists_{d|d\in tree(a)}使得d为,x,y,z的公共祖先(tree(x)表示x的子树)
则lca(x,y)=min deep of{d|d∈tree(a)}≠alca(x,y)=mindeepof{d|d∈tree(a)}≠alca(x,y)=min\ deep\ of\{d|d\in tree(a)\}\not=a与题设矛盾
当deepa>deepbdeepa>deepbdeep_a>deep_b时同理
故 对于点对(x,y,z):lca(x,z)一定是lca(x,y)和lca(y,z)中的一个

于是n-1个lca分别为某n-1对(x,y)的lca
为了避免点凌乱而导致的lca没有全部查找出来,可以将询问按照原树的dfs序排序,加入相邻两点的lca

—————————————————重点从这里开始:—————————————————

因为虚树中的的dfs序与原树相同,那么按照dfs序枚举每一个虚树中的点,用栈维护从根延下来的链,那么边信息就可以知道。

计算答案:

对于一条边(x,y)已知x,y分别被哪个点管辖,设管辖x的点为c[x],管辖y的点为c[y],当c[x]=c[y]c[x]=c[y]c[x]=c[y]则x到y都归c[x]管辖,否则,设c[x]到x的距离为dis[x],c[y]到y的距离为dis[y],x到y的距离为D(x,y)D(x,y)D(x,y),列一个二元一次方程求出x到y从哪里切断,注意c[x]和c[y]的大小关系。
那么切断的位置拥有的点数,在原树中跑一下倍增即可。

怎么求c[x]和dis[x]呢?
做树形DP:往上扫一遍用x更新fa[x],往下扫一遍用fa[x]更新x。
于是问题就快(fu)乐(za)地解决了。

#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 300100using namespace std;int n,to[N+N],nex[N+N],fir[N],dfn[N],qry[N],siz[N],fa[N],q,d[N+N],dis[N],cnt[N],head,tail,que[N];
int deep[N],tot,top,f[20][N],T,sta[N],times,is[N],Fir[N],Nex[N+N],To[N+N],in[N],Fa[N];
bool cmp(int a,int b){return dfn[a]<dfn[b];}void link(int x,int y){to[++top]=y;nex[top]=fir[x];fir[x]=top;
}
void Link(int x,int y){To[++top]=y;Nex[top]=Fir[x];Fir[x]=top;
}void dfs(){int j,i,x,y,cnt;for(head=0,fa[que[tail=1]=1]=1,deep[1]=0;head^tail;)for(i=fir[x=que[++head]],siz[x]=1;i;i=nex[i])if((y=to[i])!=fa[x])fa[que[++tail]=y]=x,deep[y]=deep[x]+1;for(head=tail;head;--head)siz[fa[que[head]]]+=siz[que[head]];for(dfn[1]=1,head=1;head<=tail;++head)for(cnt=0,i=fir[x=que[head]];i;i=nex[i])if((y=to[i])!=fa[x])dfn[y]=dfn[x]+cnt+1,cnt+=siz[y],f[0][y]=x;for(j=1;j<20;j++)for(i=1;i<=n;i++)f[j][i]=f[j-1][f[j-1][i]];
}int lca(int x,int y){if(deep[x]>deep[y])swap(x,y);for(int i=19;i>=0;i--)if(deep[f[i][y]]>=deep[x])y=f[i][y];if(x==y)return x;for(int i=19;i>=0;i--)if(f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];return f[0][x];
}int up(int x,int k){for(int i=19;i>=0;i--)if((1<<i)<=k)k-=1<<i,x=f[i][x];return x;
}int main(){freopen("worldtree.in","r",stdin);freopen("worldtree.out","w",stdout);scanf("%d",&n);for(int i=1;i<n;i++){int x,y;scanf("%d %d",&x,&y);link(x,y);link(y,x);}dfs();deep[0]=-1;scanf("%d",&q);while(q--){int m;scanf("%d",&m);tot=m;times++;for(int i=1;i<=m;i++)scanf("%d",&d[i]),cnt[d[i]]=0,is[qry[i]=d[i]]=times;sort(d+1,d+m+1,cmp);for(int i=1;i<m;i++)d[++tot]=lca(d[i],d[i+1]);sort(d+1,d+tot+1,cmp);for(int i=1,t=tot;i<=t;i++)if(i==1)tot=1;else if(d[i]!=d[i-1])d[++tot]=d[i];for(int i=1;i<=tot;i++)Fir[d[i]]=0,dis[d[i]]=n+n;top=0;sta[T=1]=d[1];for(int i=2;i<=tot;i++){while(T && siz[sta[T]]+dfn[sta[T]]<=dfn[d[i]])--T;int x=sta[T],y=d[i];Link(x,y);Link(y,x);Fa[y]=x;sta[++T]=y;}for(int i=tot;i>=1;i--){int x=d[i],o,y=Fa[x];if(is[x]==times)dis[x]=0,in[x]=x;if(i==1)continue;if(dis[x]+deep[x]-deep[y]<dis[y] || (dis[x]+deep[x]-deep[y]==dis[y] && in[x]<in[y]))dis[y]=dis[x]+deep[x]-deep[y],in[y]=in[x];}for(int i=2;i<=tot;i++){int x=Fa[d[i]],y=d[i];if(dis[x]+deep[y]-deep[x]<dis[y] || (dis[x]+deep[y]-deep[x]==dis[y] && in[x]<in[y]))dis[y]=dis[x]+deep[y]-deep[x],in[y]=in[x];}cnt[in[d[1]]]=n;for(int i=1;i<top;i+=2){int y=To[i],x=To[i+1];if(in[x]!=in[y]){int k,k2=dis[x]-dis[y]+deep[y]-deep[x];if(k2&1)k=k2/2;else k=k2/2-(in[x]<in[y]?1:0);int t=up(y,k);cnt[in[x]]-=siz[t];cnt[in[y]]+=siz[t];}}for(int i=1;i<=m;i++)printf("%d ",cnt[qry[i]]);printf("\n");}fclose(stdin);fclose(stdout);return 0;
}

世界树(worldtree)相关推荐

  1. BZOJ3572.【HNOI2014】世界树(worldtree)

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

  2. 【HNOI2014】世界树(worldtree) (虚树详解)

    题目大意 原题又臭又长,总之简介来说的话就是 给定一棵树,有若干个询问,每次给定m个点,每个点都被这m个点中最近(距离相同,编号小的近)的点管辖.问m个点分别管几个点. n<=300000,q& ...

  3. BZOJ3572: [Hnoi2014]世界树

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

  4. 【fjwc2015】世界树

    [题目描述] 奥丁杀死的巨人伊米尔后,从伊米尔的尸体上生长出来一株巨大的梣树,它是整个宇宙的核心,被称为世界之树,这个巨木的枝干构成了整个世界,它被神秘的奥术力量所守护. 奥丁发现,世界树的每个节点至 ...

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

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

  6. [2020-11-30 contest]数列(矩阵加速),秘密通道(dijkstra最短路)小X游世界树(换根dp),划分(数学)

    文章目录 数列 solution code 秘密通道 solution code 小X游世界树 solution code 划分 solution code 数列 a[1]=a[2]=a[3]=1 a ...

  7. JZOJ5776. 【NOIP2008模拟】小x游世界树

    题目:[NOIP2008模拟]小x游世界树: 题目的附加题解给的很清楚,这里只给一个代码: 1 #include<iostream> 2 #include<cstdio> 3 ...

  8. JZOJ 5776. 【NOIP2008模拟】小x游世界树

    5776. [NOIP2008模拟]小x游世界树  (File IO): input:yggdrasil.in output:yggdrasil.out Time Limits: 1500 ms  M ...

  9. [题解](树形dp/换根)小x游世界树

    2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...

  10. 虚树(bzoj 3572: [Hnoi2014]世界树)

    例题: 一棵n个节点的树,m次查询,每次查询给你一个点集U,对于树上的所有节点x(x∉U),你要找到一个点y(y∈U)满足y点离x点最近且标号最小,表示x点受y点管辖,而你的任务就是对于每次查询输出U ...

最新文章

  1. 使用maven创建项目和cannot change version web module 3.0
  2. C 语言编程 — 结构化程序流的汇编代码与 CPU 指令集
  3. 处理微信文章中防盗链问题
  4. python:__new__()与__init__()
  5. nfs服务器_Kubernetes集群下部署NFS持久存储
  6. 安装qtceator后无法启动help插件 Qt编译错误:cannot find -lGL 解决办法
  7. 关于STM32L100xx, STM32L151xx, STM32L152xx ,STM32L162xx 的Power Control
  8. lhdc协议是什么_无线耳机标注的编码是什么意思?看懂了会少很多坑
  9. python数字猜大小游戏
  10. vlan间路由+静态路由+NAT(PAT+静态NAT)综合实验
  11. 视频怎么制作动图?教你一招视频gif制作的方法
  12. 分数乘法怎么用计算机计算,分数乘法计算与简单运用
  13. linux grep -rn如何只过滤第二层的某个文件夹
  14. ps快捷键及相关基础知识总结(持续ing)
  15. 利用python制作拼图_用python做一个三阶拼图
  16. google退出后产生的影响
  17. 计算机ir领域,IR领域的相关等级会议和期刊
  18. zblog php模板偷,zblogPHP仿站+定制模板 - 模板ID code
  19. IC设计数字后端——ICC相关(2020)
  20. 【vscode】网易云音乐插件Please interact with the document first otherwise play() will failed解决方法

热门文章

  1. configure: error: Your system does not support systemd
  2. S3C2440的裸奔--内存篇(非MMU)--------转的网友 泠瑛 的博客文章在此谢过!
  3. DirectX和OPenGL 与 UE4 U3D的关系是什么?
  4. 《计算机网络 第7版》第9章 无线局域网的物理层和MAC层
  5. 【Unity】 HTFramework框架(三十九)UI的数据驱动模式,MVVM
  6. 【电路第八章】相量法
  7. Minecraft 1.18.1、1.18.2模组开发 19.拼图结构建筑(JigSaw Structure)
  8. java 拼图_Java 9:“拼图计划终于给了我们急需的Java安全带”
  9. 【每日一练】21—CSS实现炫酷动画背景
  10. 怎么关闭苹果Mac桌面出现麦克风图案?