洛谷P3233 [HNOI2014]世界树
虚树= =
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#define INF 0x7f7f7f7f
#define MAXN 300005
#define LOG 20
#define rint register int
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define ft first
#define sc second
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if('-'==ch)f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int fst1[MAXN],nxt1[MAXN<<],from1[MAXN<<],to1[MAXN<<],cnte;
int fst[MAXN],nxt[MAXN<<],from[MAXN<<],to[MAXN<<],cnt;
void add(int x,int y){
nxt[++cnt]=fst[x],fst[x]=cnt,from[cnt]=x,to[cnt]=y;
nxt[++cnt]=fst[y],fst[y]=cnt,from[cnt]=y,to[cnt]=x;
}
void add1(int x,int y){
nxt1[++cnte]=fst1[x],fst1[x]=cnte,from1[cnte]=x,to1[cnte]=y;
nxt1[++cnte]=fst1[y],fst1[y]=cnte,from1[cnte]=y,to1[cnte]=x;
}
int n,m;
int h[MAXN];
int dep[MAXN],fa[MAXN][LOG],sz[MAXN];
int dfn[MAXN],idx;
int b[MAXN],pa[MAXN];
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(rint d=dep[x]-dep[y],k=;d;d>>=,k++){
if(d&)x=fa[x][k];
}
if(x==y)return x;
for(rint k=LOG-;k>=;k--){
if(fa[x][k]!=fa[y][k]){
x=fa[x][k],y=fa[y][k];
}
}
return fa[x][];
}
void dfs1(int x){
sz[x]=;
dfn[x]=(++idx);
for(rint e=fst1[x];e;e=nxt1[e]){
int y=to1[e];
if(y!=fa[x][]){
fa[y][]=x;
dep[y]=dep[x]+;
dfs1(y);
sz[x]+=sz[y];
}
}
}
bool comp(const int &A,const int &B){
return (dfn[A]<dfn[B]);
}
bool comp1(const int A,const int &B){
return (dep[A]>dep[B]);
}
int sta[MAXN],top,rt,t[MAXN],tot;
pii d[MAXN];
void dfs(int x){
for(rint e=fst[x];e;e=nxt[e]){
int y=to[e];
if(y!=pa[x]){
d[y]=min(d[y],mp(d[x].ft+dep[y]-dep[x],d[x].sc));
dfs(y);
}
}
}
void pop(int p){
pa[sta[top]]=p;
add(sta[top],p);
b[sta[top]]=;
t[++tot]=sta[top];
top--;
}
int h1[MAXN];
void init(){
cnt=;
memset(fst,,sizeof(fst));
memset(nxt,,sizeof(nxt));
memset(from,,sizeof(from));
memset(to,,sizeof(to));
memset(b,,sizeof(b));
memset(pa,,sizeof(pa));
memcpy(h1,h,sizeof(h1));
sort(h+,h+m+,comp);
top=tot=;
sta[++top]=h[];
int x,y;
for(rint i=;i<=m;i++){
x=h[i],y=lca(x,sta[top]);
while(dep[sta[top-]]>=dep[y]){
pop(sta[top-]);
}
if(dep[sta[top]]==dep[y]){
sta[++top]=x;
}
else{
pop(y);
sta[++top]=y;
sta[++top]=x;
}
}
while(top){
pop(sta[top-]);
}
rt=sta[];
for(rint i=;i<=tot;i++)d[t[i]]=mp(INF,);
for(rint i=;i<=m;i++)d[h[i]]=mp(,h[i]);
sort(t+,t+tot+,comp1);
for(rint i=;i<=tot;i++){
x=t[i];
d[pa[x]]=min(d[pa[x]],mp(d[x].ft-dep[pa[x]]+dep[x],d[x].sc));
}
dfs(rt);
}
int ans[MAXN];
int LA(int x,int L){
for(rint k=L,p=;k;k>>=,p++){
if(k&){
x=fa[x][p];
}
}
return x;
}
int workup(int x,int f,int L){
if(L<=)return ;
int y=LA(x,min(L,dep[x]-dep[f]-));
return sz[y]-sz[x];
}
int workdown(int x,int f,int L){
if(L<=)return ;
int y=LA(x,dep[x]-dep[f]-);
int z=LA(x,max(dep[x]-dep[f]--L,));
return sz[y]-sz[z];
}
void work(int x,int f){
int t=d[f].ft+d[x].ft+dep[x]-dep[f]-;
int L=t>>;
if(t&){
ans[d[x].sc]+=workup(x,f,L-d[x].ft);
ans[d[f].sc]+=workdown(x,f,L-d[f].ft);
ans[min(d[x].sc,d[f].sc)]+=workup(x,f,L+-d[x].ft)-workup(x,f,L-d[x].ft);
}
else{
ans[d[x].sc]+=workup(x,f,L-d[x].ft);
ans[d[f].sc]+=workdown(x,f,L-d[f].ft);
}
}
void solve(){
memset(ans,,sizeof(ans));
int x;
for(rint i=;i<=tot;i++){
x=t[i];
ans[d[x].sc]+=sz[x];
int y=LA(x,dep[x]-dep[pa[x]]-);
ans[d[pa[x]].sc]-=sz[y];
}
ans[d[rt].sc]+=sz[]-sz[rt];
for(rint i=;i<=tot;i++){
x=t[i];if(x==rt)continue;
work(x,pa[x]);
}
for(rint i=;i<=m;i++){
printf("%d ",ans[h1[i]]);
}printf("\n");
}
int main()
{
// freopen("data.in","r",stdin);
n=read();
int x,y;
for(rint i=;i<n;i++){
x=read(),y=read();
add1(x,y);
}
dep[]=;
dfs1();
for(rint k=;k<LOG;k++){
for(rint i=;i<=n;i++){
fa[i][k]=fa[fa[i][k-]][k-];
}
}
int q=read();
while(q--){
m=read();
for(rint i=;i<=m;i++)h[i]=read();
init();
solve();
}
return ;
}
洛谷P3233 [HNOI2014]世界树的更多相关文章
- ●洛谷P3233 [HNOI2014]世界树
题链: https://www.luogu.org/problemnew/show/P3233题解: 虚树,dp,倍增. 首先对于每个询问,要把虚树建出来,这一步就从略了.这里着重分享一下如何求答案. ...
- 洛谷 P3233 [HNOI2014]世界树(虚树+dp)
题面 luogu 题解 数据范围已经告诉我们是虚树了,考虑如何在虚树上面\(dp\) 以下摘自hzwer博客: 构建虚树以后两遍dp处理出虚树上每个点最近的议事处 然后枚举虚树上每一条边,考虑其对两端 ...
- 洛谷P3233 世界树 [HNOI2014] 虚树
正解:虚树 解题报告: 传送门! 首先看到这种就要想到虚树这个是毫无疑问的QwQ 建虚树什么的都可以循规蹈矩地做,不说辣,具体可以看下虚树学习笔记什么的看下板子 但是建好虚树之后怎么搞还是有点儿讲究, ...
- 洛谷P3233 世界树
题意:给定树上k个关键点,每个点属于离他最近,然后编号最小的关键点.求每个关键点管辖多少点. 解:虚树 + DP. 虚树不解释.主要是DP.用二元组存虚树上每个点的归属和距离.这一部分是二次扫描与换根 ...
- 洛谷 P3237 [HNOI2014]米特运输 解题报告
P3237 [HNOI2014]米特运输 题目描述 米特是\(D\)星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. \(D\)星上有 ...
- 洛谷 P3235 [HNOI2014]江南乐 解题报告
P3235 [HNOI2014]江南乐 Description 两人进行 T 轮游戏,给定参数 F ,每轮给出 N 堆石子,先手和后手轮流选择石子数大于等于 F 的一堆,将其分成任意(大于1)堆,使得 ...
- 洛谷P3237 [HNOI2014]米特运输(树形dp)
解题报告 题干 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. D星上有N个城市,我们将其顺序编号为1到N,1号城市为首都. ...
- 洛谷P3235 [HNOI2014]江南乐(Multi-SG)
题目描述 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏. 游戏的规则是这样的,首先给定一个数F,然后游戏系统 ...
- luogu P3233 [HNOI2014]世界树
传送门 我是什么时候写的这题的qwq 首先,发现关键点的总数被限制了,很自然想到虚树,并且,对于一个关键点,他管理的点显然是一个联通块 然后把虚树先建出来,然后两次dfs,第一次是向祖先更新离每个点最 ...
随机推荐
- Linux下I/O多路转接之epoll(绝对经典)
epoll 关于Linux下I/O多路转接之epoll函数,什么返回值,什么参数,我不想再多的解释,您不想移驾,我给你移来: http://blog.csdn.net/colder2008/artic ...
- iOS开发-添加圆角效果高效实现
圆角(RounderCorner)是一种很常见的视图效果,相比于直角,它更加柔和优美,易于接受.但很多人并不清楚如何设置圆角的正确方式和原理.设置圆角会带来一定的性能损耗,如何提高性能是另一个需要重点 ...
- Flask-uploads 简单使用
pip install flask-uploads#先导入次此处需要用到的库: from flask_uploads import UploadSet, IMAGES, configure_uploa ...
- Hibernate之深入Hibernate的映射文件
这周周末 要把hibernate的映射文件搞定 .. 1.映射文件的主结构 主要结构 :根元素为<hibernate-mapping ></hibernate-mapping> ...
- Python 列表嵌套多种实现方式
#coding=utf-8 list=[] for i in range(1,101): list.append(i) # print(list) tempList=[] newList=[] whi ...
- php代码一样,编码不同报错
php代码一样,编码不同报错 两个php代码完全一样,但是就报错,比如说声明比如在very first,这种,可以把编码设置utf-8 无bom
- 第一次制作和使用图标字体-IcoMoon
开题:之前就有所耳闻,最近两天第一次运用到图标字体.刚开始嘛,一脸懵逼的状态.成功运用之后就来记录一下使用过程咯! 1. 打开在线生成工具:https://icomoon.io/app/#/selec ...
- 4-51单片机WIFI学习(开发板51单片机自动冷启动下载原理)
上一篇链接 http://www.cnblogs.com/yangfengwu/p/8743936.html 这一篇说一下自己板子的51单片机自动冷启动下载原理,我挥舞着键盘和鼠标,发誓要把世界写个明 ...
- eclipse+Maven插件报错:-Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match.
问题描述: eclipse indigo+maven3.3.3+jdk1.70 maven插件执行报错:-Dmaven.multiModuleProjectDirectory system prope ...
- Docker学习笔记 - Docker容器之间的连接
学习目标: 容器之间可以相互连接访问:: --link redis:redisAlias 准备工作 FROM ubuntu:14.04 RUN apt-get install -y ping RUN ...