洛谷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,第一次是向祖先更新离每个点最 ...
随机推荐
- Beta第五天
听说
- 201621123062《java程序设计》第六周作业总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰 ...
- 《Language Implementation Patterns》之 增强解析模式
上一章节讲述了基本的语言解析模式,LL(k)足以应付大多数的任务,但是对一些复杂的语言仍然显得不足,已付出更多的复杂度.和运行时效率为代价,我们可以得到能力更强的Parser. Pattern 5 : ...
- 团队作业7——第二次项目冲刺(Beta版本12.05-12.07)
1.当天站立式会议照片 本次会议内容:1:每个人汇报自己完成的工作.2:组长分配各自要完成的任务. 2.每个人的工作 黄进勇:项目整合,后台代码. 李勇:前台界面优化. 何忠鹏:数据库模块. 郑希彬: ...
- python 一致性哈希 分布式
hash_ring # -*- coding: utf-8 -*- """ hash_ring ~~~~~~~~~~~~~~ Implements consistent ...
- R语言基础2
----------------------------------R语言学习与科研应用,科研作图,数据统计挖掘分析,群:719954246-------------------------- 通常, ...
- DBA 小记 — 分库分表、主从、读写分离
前言 我在上篇博客 "Spring Boot 的实践与思考" 中比对不同规范的 ORM 框架应用场景的时候提到过主从与读写分离,本篇随笔将针对此和分库分表进行更深入地探讨. 1. ...
- $(function(){})和window.onload的区别
(1)$(function(){}):DOM节点创建 完成才执行 (2)window.onload:页面所有资源(JS/CSS)加载完成才执行
- 使用HTML5视频事件示例
<!DOCTYPE html > <html > <head> <title>Video events example</title> &l ...
- MYSQL之视图、触发器、存储过程、函数、事物、数据库锁和数据库备份
一.视图 -- view 视图:是一个虚报表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据. 视图有如下特点: 1.视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系 ...