洛谷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,第一次是向祖先更新离每个点最 ...
随机推荐
- 冲刺NO.6
Alpha冲刺第六天 站立式会议 项目进展 项目中学生基本信息管理,与系统管理员模块基本完成,团队开始编写学生信用信息模块内容与奖惩事务管理内容,准备开始对已完成模块进行测试. 问题困难 团队成员对前 ...
- python functools.lru_cache做备忘功能
import time import functools def clock(func): @functools.wraps(func)#还原被装饰函数的__name__和__doc__属性 def ...
- 关于collectionView和tableView的两种cell的出列方法的区别
相信好多人一定会对collectionView和tableView的两种cell出列方法有所疑问,下面以UICollection为例子进行举例说明 假设我们已经创建了一个collectionView, ...
- [Redis源码阅读]redis持久化
作为web开发的一员,相信大家的面试经历里少不了会遇到这个问题:redis是怎么做持久化的? 不急着给出答案,先停下来思考一下,然后再看看下面的介绍.希望看了这边文章后,你能够回答这个问题. 为什么需 ...
- EasyUI内容页Tabs。
html: <div data-options="region:'center'"> <div id="tabs" class="e ...
- Nagios监控的部署与配置
[安装Nagios] yum install -y httpd httpd-devel httpd-tools mysql mysql-devel mysql-server php php-devel ...
- 怎样使用下载的bootstrap模板?
核心文件bootstarp.css和bootstarp.js导入到页面,然后看着官网的代码复制进去用就可以了.网上是有不少教程的.实际上就是加class 属性 ,如:http://www.runoob ...
- IntelliJ IDEA开发Scala代码,与java集成,maven打包编译
今天尝试了一下在IntelliJ IDEA里面写Scala代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给IntelliJ IDEA安装一下Scala的插件,在IDEA的启 ...
- Spring-Boot导入配置文件与取值
前言: springboot简化了大量配置文件,但是必要时还是需要导入配置文件的,比如dubbo,此处简记之. 正文: 所有的配置文件引入都是使用注解在类上进行引入的,常用的有两种注解@Propert ...
- 深度理解DOM拷贝clone()
克隆节点是DOM的常见操作,jQuery提供一个clone方法,专门用于处理dom的克隆: .clone()方法深度 复制所有匹配的元素集合,包括所有匹配元素.匹配元素的下级元素.文字节点. clon ...