luogu3233 世界树 (虚树)
反正肯定要建虚树,考虑建完之后怎么做
先随便dp一下算出来距离某点最近的询问点mi[x](因为有的虚树上的点它不是询问点嘛)
那我们对于某条链x到fa[x]上的非虚树上的点(包括他们的非虚树上的孩子),要么把它分给mi[x],要么分给mi[fa[x]]
我找到这个中间点以后,在原树上倍增跳过去,算他的size
这个分法是以$\frac{len[mi[x]]+len[x]+len[mi[fa[x]]]}{2}$再加加减减一些细节决定的(len[x]表示x到fa[x]的链的长度)
除此之外,每个在虚树上的点x(以及它不在虚树上的孩子),都归属于mi[x]
#include<bits/stdc++.h>
#define mp make_pair
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pa;
const int maxn=3e5+,inf=1e9; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,Q;
int eg[maxn*][],egh[maxn],ect;
int fa[maxn][],dep[maxn],dfn[maxn],tot,siz[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} inline void dfs1(int x){
dfn[x]=++tot;
for(int i=;fa[x][i]&&fa[fa[x][i]][i];i++){
fa[x][i+]=fa[fa[x][i]][i];
}
siz[x]=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
fa[b][]=x,dep[b]=dep[x]+;
dfs1(b);siz[x]+=siz[b];
}
} inline int jump(int x,int d){
int i=;
while(d){
if(d&) x=fa[x][i];
i++,d>>=;
}return x;
} inline int getlca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=log2(dep[x]-dep[y]);i>=&&dep[x]!=dep[y];i--){
if(dep[fa[x][i]]>=dep[y])
x=fa[x][i];
}
if(x==y) return x;
for(int i=log2(dep[x]);i>=;i--){
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
}
return fa[x][];
} inline bool cmp(int x,int y){return dfn[x]<dfn[y];} int xfa[maxn],xsh[maxn],xbr[maxn]; int h[maxn],stk[maxn],hd,len[maxn];
int ans[maxn],id[maxn],pct;
bool rea[maxn];
inline void connect(int x,int y){
// printf("\t\tconnect:%d %d\n",x,y);
xfa[x]=y,xbr[x]=xsh[y],xsh[y]=x,len[x]=dep[x]-dep[y];
}
inline void build(int m){
sort(h+,h+m+,cmp);
stk[hd=]=;id[++pct]=;
for(int i=;i<=m;i++){
rea[h[i]]=;id[++pct]=h[i];
int lca=getlca(stk[hd],h[i]);
int lst=;
while(dfn[stk[hd]]>dfn[lca]){
if(lst) connect(lst,stk[hd]);
lst=stk[hd--];
}if(stk[hd]!=lca) stk[++hd]=lca,id[++pct]=lca;
if(lst) connect(lst,stk[hd]);
if(h[i]!=) stk[++hd]=h[i];
}
while(hd>) connect(stk[hd],stk[hd-]),hd--;
}
pa up[maxn],dw[maxn];
inline void dfs2(int x){
if(rea[x]) dw[x]=mp(,x);
else dw[x]=mp(inf,);
for(int i=xsh[x];i;i=xbr[i]){
dfs2(i);
dw[x]=min(dw[x],mp(dw[i].first+len[i],dw[i].second));
}
}
inline void dfs3(int x){
if(rea[x]) up[x]=mp(,x);
else if(x==) up[x]=mp(inf,);
pa m=mp(inf,),s=mp(inf,);
for(int i=xsh[x];i;i=xbr[i]){
s=min(s,mp(dw[i].first+len[i],dw[i].second));
if(s<m) swap(s,m);
}
for(int i=xsh[x];i;i=xbr[i]){
up[i]=mp(up[x].first+len[i],up[x].second);
if(dw[i].first+len[i]==m.first&&dw[i].second==m.second){
up[i]=min(up[i],mp(s.first+len[i],s.second));
}else up[i]=min(up[i],mp(m.first+len[i],m.second));
dfs3(i);
}
if(x!=){
int n=min(dw[x],up[x]).first+len[x]+min(dw[xfa[x]],up[xfa[x]]).first,mi=min(dw[xfa[x]],up[xfa[x]]).second;
if(!(n&)&&mi<min(dw[x],up[x]).second) n--;
n>>=,n-=min(dw[x],up[x]).first;
if(n>len[x]) n--;
if(n>=){
int y=jump(x,n),z=jump(x,len[x]-);
ans[min(dw[x],up[x]).second]+=siz[y]-siz[x],ans[mi]+=siz[z]-siz[y];
} }
int ss=siz[x];
for(int i=xsh[x];i;i=xbr[i]) ss-=siz[jump(i,len[i]-)];
ans[min(dw[x],up[x]).second]+=ss;
} int hh[maxn];
int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}dep[]=;dfs1();
// for(i=1;i<=N;i++) printf("~%d %d\n",i,siz[i]);
Q=rd();
for(i=;i<=Q;i++){
int m=rd();
for(j=;j<=m;j++) hh[j]=h[j]=rd();
build(m);
dfs2(),dfs3();
for(j=;j<=m;j++) printf("%d ",ans[hh[j]]);
printf("\n");
for(;pct;pct--) xfa[id[pct]]=xbr[id[pct]]=xsh[id[pct]]=rea[id[pct]]=ans[id[pct]]=;
}
return ;
}
/*
21
1 2
2 3
2 4
3 9
4 5
5 6
6 7
6 8
2 18 2 19 2 20 2 21
9 13 9 14
5 17
4 15 4 16
6 10 10 11 10 12
1
3
9 7 8
*/
luogu3233 世界树 (虚树)的更多相关文章
- 【BZOJ-3572】世界树 虚树 + 树形DP
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1084 Solved: 611[Submit][Status ...
- bzoj 3572: [Hnoi2014]世界树 虚树 && AC500
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 520 Solved: 300[Submit][Status] ...
- 【BZOJ3572】[Hnoi2014]世界树 虚树
[BZOJ3572][Hnoi2014]世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森 ...
- bzoj 3572: [Hnoi2014]世界树 虚树
题目: Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生 ...
- bzoj3572[Hnoi2014] 世界树 虚树+dp+倍增
[Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1921 Solved: 1019[Submit][Status][Dis ...
- BZOJ 3572 世界树(虚树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3572 思路:建立虚树,然后可以发现,每条边不是同归属于一端,那就是切开,一半给上面,一半给下面. # ...
- bzoj 3572世界树 虚树+dp
题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...
- BZOJ 3572: [Hnoi2014]世界树 [虚树 DP 倍增]
传送门 题意: 一棵树,多次询问,给出$m$个点,求有几个点到给定点最近 写了一晚上... 当然要建虚树了,但是怎么$DP$啊 大爷题解传送门 我们先求出到虚树上某个点最近的关键点 然后枚举所有的边$ ...
- bzoj 3572 [Hnoi2014]世界树——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3572 关于虚树:https://www.cnblogs.com/zzqsblog/p/556 ...
随机推荐
- python文件封装成*.exe文件(单文件和多文件)
环境:win10 64位 python3.7 单*.py文件打包Python GUI:程序打包为exe 一.安装Pyinstaller,命令pip install Pyinstaller,(大写的P ...
- <c:forEach varStatus="status">中 varStatus的作用
varStatus是<c:forEach>jstl循环标签的一个属性,varStatus属性. varStatus=“status”事实上定义了一个status名的对象作为varStatu ...
- 基于vue-cli,sass,vant的移动端项目
项目架构 开始 vue init webpack 项目名称 //新建项目,cd进入新项目 npm install axios //先安装! ...
- Spring的Bean配置
IOC和DI 网上概念很多,感兴趣可以去搜一搜,在这里我就给个比喻: IOC:以前我们买东西都要去商店买,用了IOC之后,我们只要在门口放个箱子, Spring就会给我相应商品,ಠᴗಠ 举个例子 cl ...
- linux查看端口是否开放
在讨论这个问题前,我们先来了解一下物理端口.逻辑端口.端口号等计算机概念. 端口相关的概念: 在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型.物理端口指的是物理存在的端口,如ADSL M ...
- com.alibaba的fastjson简介
fastjson简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSO ...
- comparable和comparator
Comparable Comparable可以认为是一个内部比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,在compareTo方法中指定具体的比较方法. comp ...
- QTP 自动货测试桌面程序-笔记(添加控件仓库并关联到action)
录制或编写脚本前先添加行为对应的控件仓库: 心得:多个测试action使用的同一个窗体的仓库单独放于一个仓库中,可以在多个action中添加关联使用 将同一个窗体的控件只放于一个仓库中,减少使用时的名 ...
- SQL Server与SQL Server Express的区别
SQL Server Express 2005(以下简称 SQLExpress) 是由微软公司开发的 SQL Server 2005(以下简称 SQL2005)的缩减版,这个版本是免费的,它继承了 S ...
- npm安裝、卸載、刪除、撤銷發佈包、更新版本信息
利用npm安裝包: 全局安裝:npm install -g 模塊安裝 局部安裝(可以使用repuire(‘模塊名’)引用):npm install 模塊名稱 如果權限不夠,就是用管理員方式安裝. 本地 ...