解题: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号城市 ...
随机推荐
- Vue 使用细节收集
JSX 中 on 开头的属性名 在用 elementui 中的 el-upload 的时候,他们组件中有一个属性 on-change ,也不知道谁想出来的属性名,太扯淡了,非要 on 开头,我开始的代 ...
- sinopia 搭建记录
最近公司有个问题,一些公共部分每次都要手动发送,放到 git 上涉及到父子 git 问题,现在就想在内部搭建一个 npm,涉及到公共模块了就直接 npm update 更新一下.找到了 sinopia ...
- mfc 虚函数
知识点 类虚函数概念 类虚函数定义virtual 一.虚函数 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数. 二.虚函数定义 定义:在某基类中声明为 virtual 并在一个或多个派 ...
- LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]
题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...
- github协同开发
看官请移步GitHub团队项目合作流程 本文是上述链接的截图,担心哪天作者不小心删除了,备一份在自己这里,仅为自己看着方便.侵权请告知
- Redis发布订阅和事物笔记
Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 cha ...
- 设计模式 笔记 迭代器模式 Iterator
//---------------------------15/04/26---------------------------- //Iterator 迭代器模式----对象行为型模式 /* 1:意 ...
- Mac 上flink的安装与启动
在Mac 上安装flink,需要通过Homebrew安装的 1.howmebrew的安装方式,在终端粘贴以下命令,或者去官网https://brew.sh/index_zh-cn 找到此代码复制粘贴到 ...
- Nginx安装负载均衡配置 fair check扩展
前言 本文主要是针对Nginx安装.负载均衡配置,以及fair智能选举.check后端节点检查扩展功能如何扩展,进行讲解说明. fair模块: upstream-fair,“公平的”Nginx 负载均 ...
- java数据结构之hashMap
初学JAVA的时候,就记得有句话两个对象的hashCode相同,不一定equal,但是两个对象equal,hashCode一定相同,当时一直不理解是什么意思,最近在极客时间上学习了课程<数据结构 ...