解题:HNOI 2014 世界树
首先建虚树
DFS求虚树上每个点所属的点和到它所属点的距离,然后在=考虑虚树所有的边(对应原树一条链)。如果两个端点所属节点不同就倍增出分界点统计答案,否则不用管(之后会统计到的);注意根节点特殊讨论。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=,inf=1e9;
int T,n,m,t1,t2,cnt,tot,top;
int p[N],noww[N],goal[N];
int siz[N],dep[N],dfn[N],upt[N][K],oth[N][K];
int a[N],b[N],c[N],d[N],bel[N],stk[N],ans[N];
bool cmp(int a,int b)
{
return dfn[a]<dfn[b];
}
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth,int dth)
{
siz[nde]=,dep[nde]=dth;
upt[nde][]=fth,dfn[nde]=++tot;
for(int i=;i<=&&upt[nde][i-];i++)
upt[nde][i]=upt[upt[nde][i-]][i-];
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
DFS(goal[i],nde,dth+),siz[nde]+=siz[goal[i]];
}
void Calc(int nde,int fth)
{
oth[nde][]=siz[fth]-siz[nde];
for(int i=;i<=&&upt[nde][i-];i++)
oth[nde][i]=oth[nde][i-]+oth[upt[nde][i-]][i-];
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth) Calc(goal[i],nde);
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;dep[x]!=dep[y];i--)
if(dep[upt[x][i]]>=dep[y]) x=upt[x][i];
if(x==y) return x;
for(int i=;~i;i--)
if(upt[x][i]!=upt[y][i])
x=upt[x][i],y=upt[y][i];
return upt[x][];
}
int Dis(int x,int y)
{
int lca=LCA(x,y);
return dep[x]+dep[y]-*dep[lca];
}
bool Check(int a,int b,int d)
{
return c[a]+d<c[b]||(c[a]+d==c[b]&&bel[a]<bel[b]);
}
void Insert(int nde)
{
if(!top) stk[++top]=nde;
else
{
int lca=LCA(nde,stk[top]);
if(lca!=stk[top])
{
while(top>&&dfn[lca]<=dfn[stk[top-]])
Link(stk[top-],stk[top]),top--;
if(dfn[lca]<dfn[stk[top]])
Link(lca,stk[top]),top--;
if(lca!=stk[top])
stk[++top]=lca;
}
stk[++top]=nde;
}
}
int Upt(int nde,int gal)
{
int ret=;
for(int i=;~i;i--)
if(gal&(<<i))
ret+=oth[nde][i],nde=upt[nde][i];
return ret;
}
void DFS1(int nde)
{
if(!bel[nde]) c[nde]=inf;
for(int i=p[nde];i;i=noww[i])
{
int g=goal[i],dd=dep[g]-dep[nde]; DFS1(g);
if(Check(g,nde,dd)) c[nde]=c[g]+dd,bel[nde]=bel[g];
}
}
void DFS2(int nde,int lst)
{
int dd=dep[nde]-dep[lst];
if(lst&&Check(lst,nde,dd))
c[nde]=c[lst]+dd,bel[nde]=bel[lst];
for(int i=p[nde];i;i=noww[i])
DFS2(goal[i],nde),d[nde]+=d[goal[i]];
if(!lst) ans[bel[nde]]+=n-d[nde];
else if(bel[nde]!=bel[lst])
{
int cut=c[nde]+c[lst]+dd,chk=cut%||bel[nde]<bel[lst],tmp;
tmp=Upt(nde,cut/-c[nde]-(chk^));
ans[bel[nde]]+=siz[nde]-d[nde]+tmp,d[nde]=siz[nde]+tmp;
}
}
void Clear(int nde)
{
for(int i=p[nde];i;i=noww[i])
Clear(goal[i]);
bel[nde]=p[nde]=c[nde]=d[nde]=;
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d%d",&t1,&t2),Link(t1,t2),Link(t2,t1);
DFS(,,),Calc(,),memset(p,,sizeof p);
scanf("%d",&T);
while(T--)
{
scanf("%d",&m),cnt=top=;
for(int i=;i<=m;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(a+,a++m,cmp); stk[top=]=a[],bel[a[]]=a[];
for(int i=;i<=m;i++) Insert(a[i]),bel[a[i]]=a[i];
while(top>) Link(stk[top-],stk[top]),top--;
DFS1(stk[]),DFS2(stk[],);
for(int i=;i<=m;i++)
printf("%d ",ans[b[i]]),ans[b[i]]=;
Clear(stk[]),puts("");
}
return ;
}
解题:HNOI 2014 世界树的更多相关文章
- 数据结构(虚树,动态规划):HNOI 2014 世界树
Hnoi2014 世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平 ...
- [HNOI 2014]世界树
Description 题库链接 给出一棵 \(n\) 个节点的树, \(q\) 次询问,每次给出 \(k\) 个关键点.树上所有的点会被最靠近的关键点管辖,若距离相等则选编号最小的那个.求每个关键点 ...
- HNOI 2014 米特运输(图论)
HNOI 2014 米特运输 题目大意 给一棵树,每个点有自己的权值,要求更改一些点的权值,使得整棵树满足两个条件: 同一个父亲的所有子节点权值相同 父节点的取值为所有子节点的和 答案输出最少要更改的 ...
- HNOI 2014
D1T1:画框 frame 题意:给你两个n阶正整数方阵,请你求最大的\( \sum_{i = 1}^{n} A_{i, p_i}\times \sum_{i = 1}^{n} B_{i, p_i} ...
- 图论(KM算法,脑洞题):HNOI 2014 画框(frame)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABPoAAANFCAIAAABtIwXVAAAgAElEQVR4nOydeVxTV/r/n9ertaJEC4
- [HNOI 2014]画框
Description 题库链接 \(T\) 组询问,每组询问给你个 \(2\times N\) 的带权二分图,两个权值 \(a,b\) ,让你做匹配使得 \[\sum a\times \sum b\ ...
- [HNOI 2014]江南乐
Description 题库链接 给你指定一个数 \(f\) ,并给你 \(T\) 组游戏,每组有 \(n\) 堆石子, \(A,B\) 两人轮流对石子进行操作,每次你可以选择其中任意一堆数量不小于 ...
- [HNOI 2014]道路堵塞
Description A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国 交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有 ...
- [HNOI 2014]米特运输
Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储 存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市 ...
随机推荐
- WPF中ListBox /ListView如何改变选中条背景颜色
适用ListBox /ListView WPF中LISTVIEW如何改变选中条背景颜色 https://www.cnblogs.com/sjqq/p/7828119.html
- 20155227《网络对抗》Exp3 免杀原理与实践
20155227<网络对抗>Exp3 免杀原理与实践 实践内容 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等 ...
- 20155311《网络对抗》PC平台逆向破解(二)
20155311<网络对抗>PC平台逆向破解(二) shellcode注入 什么是shellcode? shellcode是一段代码,溢出后,执行这段代码能开启系统shell. 前期准备- ...
- python 回溯法 子集树模板 系列 —— 2、迷宫问题
问题 给定一个迷宫,入口已知.问是否有路径从入口到出口,若有则输出一条这样的路径.注意移动可以从上.下.左.右.上左.上右.下左.下右八个方向进行.迷宫输入0表示可走,输入1表示墙.为方便起见,用1将 ...
- BZOJ1000-1099板刷计划(附题解链接)
BZOJ1000-1099板刷计划 感觉完全做不动啊... \(Orz\) \(M\_sea\)板刷bzoj狂魔 1000 - 1009 1000 ...懒得说了 1001 懒得平面图转对偶图,最小割 ...
- CCNode详解
cocos2d的所有类都以CC开头,那么实际上这个类的名字就是Node,类如其名,这个类的实例就是一个节点.Cocos2d的类是树状继承的,而在内存中,各个实例之间也是以“树”这种数据结构相关联的., ...
- vue中v-if 和 v-show的区别
简单来说,v-if 的初始化较快,但切换代价高:v-show 初始化慢,但切换成本低 1.共同点 v-if 和 v-show 都可以动态地显示DOM元素 2.区别 (1)手段: v-if 是动态的向D ...
- 【转】Spring Boot干货系列:(一)优雅的入门篇
转自Spring Boot干货系列:(一)优雅的入门篇 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社区中热度一直很高,所以决定花时间来了解和学习,为自己做 ...
- 在WebGL场景中建立游戏规则
在前三篇文章的基础上,为基于Babylon.js的WebGL场景添加了类似战棋游戏的基本操作流程,包括从手中选择单位放入棋盘.显示单位具有的技能.选择技能.不同单位通过技能进行交互.处理交互结果以及进 ...
- 机器学习1—简介及Python机器学习环境搭建
简介 前置声明:本专栏的所有文章皆为本人学习时所做笔记而整理成篇,转载需授权且需注明文章来源,禁止商业用途,仅供学习交流.(欢迎大家提供宝贵的意见,共同进步) 正文: 机器学习,顾名思义,就是研究计算 ...