BZOJ 3572: [Hnoi2014]世界树

时间:2022-10-14 00:02:09

BZOJ 3572: [Hnoi2014]世界树

标签(空格分隔): OI-BZOJ OI-虚数 OI-树形dp OI-倍增


Time Limit: 20 Sec

Memory Limit: 512 MB


Description

世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界。在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息、持续运转的根本基石。

世界树的形态可以用一个数学模型来描述:世界树中有n个种族,种族的编号分别从1到n,分别生活在编号为1到n的聚居地上,种族的编号与其聚居地的编号相同。有的聚居地之间有双向的道路相连,道路的长度为1。保证连接的方式会形成一棵树结构,即所有的聚居地之间可以互相到达,并且不会出现环。定义两个聚居地之间的距离为连接他们的道路的长度;例如,若聚居地a和b之间有道路,b和c之间有道路,因为每条道路长度为1而且又不可能出现环,所卧a与c之间的距离为2。

出于对公平的考虑,第i年,世界树的国王需要授权m[i]个种族的聚居地为临时议事处。对于某个种族x(x为种族的编号),如果距离该种族最近的临时议事处为y(y为议事处所在聚居地的编号),则种族x将接受y议事处的管辖(如果有多个临时议事处到该聚居地的距离一样,则y为其中编号最小的临时议事处)。

现在国王想知道,在q年的时间里,每一年完成授权后,当年每个临时议事处将会管理多少个种族(议事处所在的聚居地也将接受该议事处管理)。 现在这个任务交给了以智慧著称的灵长类的你:程序猿。请帮国王完成这个任务吧。

Input

第一行为一个正整数n,表示世界树中种族的个数。

接下来n-l行,每行两个正整数x,y,表示x聚居地与y聚居地之间有一条长度为1的双

向道路。接下来一行为一个正整数q,表示国王询问的年数。

接下来q块,每块两行:

第i块的第一行为1个正整数m[i],表示第i年授权的临时议事处的个数。

第i块的第二行为m[i]个正整数h[l]、h[2]、…、h[m[i]],表示被授权为临时议事处的聚居地编号(保证互不相同)。

Output

输出包含q行,第i行为m[i]个整数,该行的第j(j=1,2…,,m[i])个数表示第i年被授权的聚居地h[j]的临时议事处管理的种族个数。

Sample Input

10

2 1

3 2

4 3

5 4

6 1

7 3

8 3

9 4

10 1

5

2

6 1

5

2 7 3 6 9

1

8

4

8 7 10 3

5

2 9 3 5 8

Sample Output

1 9

3 1 4 1 1

10

1 1 3 5

4 1 3 1 1

HINT

N<=300000, q<=300000,m[1]+m[2]+…+m[q]<=300000


Solution####

虚树,居然到现在才搞,真的太弱了,参考神牛http://lazycal.logdown.com/posts/202331-bzoj3572

orz


Code####

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
#define LL long long
#define MP(a,b) make_pair(a,b)
#define PA pair<int,int>
int read()
{
int s=0,f=1;char ch=getchar();
while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*f;
}
const int N=300005;
int n,m;
int be[N],bn[N*2],bv[N*2],bl[N*2],bw=1;
void put(int u,int v,int l)
{bw++;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
int dep[N],dep2[N],siz[N];
int dfn[N],rank[N],dtot;
int fa[N][19];
int h[N],t[N],tot;
void dfs(int x)
{
dfn[rank[x]=++dtot]=x;
siz[x]=1;
for(int i=be[x],v;i;i=bn[i])
if(!siz[v=bv[i]])
{fa[v][0]=x;
for(int j=0;fa[v][j+1]=fa[fa[v][j]][j];j++);
dep[v]=dep[x]+bl[i];
dep2[v]=dep[x]+1;
dfs(v);
siz[x]+=siz[v];
}
}
int lca(int a,int b)
{
if(dep2[a]<dep2[b])swap(a,b);
for(int i=18;i>=0;i--)
if(dep2[fa[a][i]]>=dep2[b])
a=fa[a][i];
for(int i=18;i>=0;i--)
if(fa[a][i]!=fa[b][i])
a=fa[a][i],b=fa[b][i];
return a==b?a:fa[a][0];
}
int jump(int x,int dis)
{
for(int i=18;i>=0;i--)
if(dep[fa[x][i]]>dis)
x=fa[x][i];
return x;
}
bool cmp(int a,int b)
{
return rank[a]<rank[b];
}
int sta[N],top;
int father[N],ans[N],val[N],hh[N];
PA md[N];
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read();
for(int i=1;i<n;i++)
{int u=read(),v=read();
put(u,v,1);
put(v,u,1);
}
dep[0]=dep2[0]=-1;
dfs(1);
for(int Q=read();Q--;)
{m=read();tot=0;
for(int i=1;i<=m;i++)
{hh[i]=h[i]=read(),
md[h[i]]=MP(0,h[i]);
t[++tot]=h[i];
ans[h[i]]=0;
}
sort(&h[1],&h[m+1],cmp);
top=0;
for(int i=1;i<=m;i++)
{int now=h[i];
if(!top){father[sta[++top]=now]=0;continue;}
int LCA=lca(sta[top],now);
for(;dep[sta[top]]>dep[LCA];top--)
if(dep[sta[top-1]]<=dep[LCA])
father[sta[top]]=LCA;
if(sta[top]!=LCA)
{t[++tot]=LCA;
father[LCA]=sta[top];
md[LCA]=MP(0x3f3f3f3f,0);
sta[++top]=LCA;
}
father[now]=sta[top];
sta[++top]=now;
}
for(int i=1;i<=tot;i++)val[t[i]]=siz[t[i]];
sort(&t[1],&t[tot+1],cmp);
for(int i=tot;i>1;i--)
{int x=t[i],f=father[x];
md[f]=min(md[f],MP(dep[x]-dep[f]+md[x].first,md[x].second));
}
for(int i=2;i<=tot;i++)
{int x=t[i],f=father[x];
md[x]=min(md[x],MP(dep[x]-dep[f]+md[f].first,md[f].second));
}
for(int i=1;i<=tot;i++)
{int x=t[i],f=father[x];
if(i==1)
{ans[md[x].second]+=n-siz[x];
continue;
}
int u=jump(x,dep[f]);
val[f]-=siz[u];
if(md[f].second==md[x].second)
{ans[md[f].second]+=siz[u]-siz[x];
continue;
}
int mid=jump(x,(md[x].first-md[f].first+dep[x]+dep[f]-(md[x].second<md[f].second))/2);
ans[md[f].second]+=siz[u]-siz[mid];
ans[md[x].second]+=siz[mid]-siz[x];
}
for(int i=1;i<=tot;i++)
ans[md[t[i]].second]+=val[t[i]];
for(int i=1;i<=m;i++)
printf("%d ",ans[hh[i]]);printf("\n");
}
//fclose(stdin);
//fclose(stdout);
return 0;
}

BZOJ 3572: [Hnoi2014]世界树的更多相关文章

  1. bzoj 3572&colon; &lbrack;Hnoi2014&rsqb;世界树 虚树 &amp&semi;&amp&semi; AC500

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 520  Solved: 300[Submit][Status] ...

  2. bzoj 3572 &lbrack;Hnoi2014&rsqb;世界树(虚树&plus;DP)

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 645  Solved: 362[Submit][Status] ...

  3. bzoj 3572 &lbrack;Hnoi2014&rsqb;世界树——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3572 关于虚树:https://www.cnblogs.com/zzqsblog/p/556 ...

  4. BZOJ 3572&colon; &lbrack;Hnoi2014&rsqb;世界树 虚树 树形dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=3572 http://hzwer.com/6804.html 写的时候参考了hzwer的代码,不会写 ...

  5. bzoj 3572&colon; &lbrack;Hnoi2014&rsqb;世界树 虚树

    题目: Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生 ...

  6. BZOJ 3572 &lbrack;HNOI2014&rsqb;世界树 &lpar;虚树&plus;DP&rpar;

    题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...

  7. BZOJ 3572&colon; &lbrack;Hnoi2014&rsqb;世界树 &lbrack;虚树 DP 倍增&rsqb;

    传送门 题意: 一棵树,多次询问,给出$m$个点,求有几个点到给定点最近 写了一晚上... 当然要建虚树了,但是怎么$DP$啊 大爷题解传送门 我们先求出到虚树上某个点最近的关键点 然后枚举所有的边$ ...

  8. 【BZOJ】3572&colon; &lbrack;Hnoi2014&rsqb;世界树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3572 算是细节题了吧.. 构出虚树,考虑z正反DP两次求出虚树中每个点最近的议事处是哪一个 ...

  9. 【BZOJ】3572&colon; &lbrack;Hnoi2014&rsqb;世界树 虚树&plus;倍增

    [题意]给定n个点的树,m次询问,每次给定ki个特殊点,一个点会被最近的特殊点控制,询问每个特殊点控制多少点.n,m,Σki<=300000. [算法]虚树+倍增 [题解]★参考:thy_asd ...

随机推荐

  1. C&num;基础-关于用json给控制台程序传值的坑

    上周遇到了一个非常诡异的坑,首先写了两个程序,第一个程序输出成dll,第二个程序是控制台程序. 在第一个程序里,我使用了process去启动第二个程序,同时传入了一个Json作为参数,即: Proce ...

  2. mvc 中的 &lbrack;ChildActionOnly&rsqb; 和 &lbrack;NonAction&rsqb;

    首先,NonAction表示它不是一个真正的Action,而是一个普通方法, 就像我们定义一个普通的方法那样,返回值可以任意定义; 而  ChildActionOnly表示它只能在View中通过Htm ...

  3. LRU缓存实现&lpar;Java&rpar;

    LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...

  4. 《Java数据结构与算法》笔记-CH4-6优先级队列

    /** * 优先级队列 * 效率:插入O(n),删除O(1).第12章介绍如何通过堆来改进insert时间 */ class PriorityQueue { private int maxSize; ...

  5. 在Linux终端下使用代理访问网络&lpar;转&rpar;

    最近,需要在linux环境下使用脚本进行一些网络访问(主要是HTTP请求与文件下载),于是查阅了一些关于代理的资料. 以下是尝试的几种代理设置方法,以供参考: 一.使用wget命令进行代理访问 wge ...

  6. 【swift-总结】函数

    swift的函数在swift2中的使用改变了不少 /** *param: personName 參数 *returns: String为返回值 */ func sayHello(personName: ...

  7. rocketmq4&period;x快速入门指南

    以下采用的是apache rocketmq 4.2.0版本 相关文档如下 快速体验: http://blog.seoui.com/2018/07/24/rocketmqinstall/ rocketm ...

  8. 047、管理Docker Machine(2019-03012 周二)

    参考https://www.cnblogs.com/CloudMan6/p/7248188.html     用docker-machine创建machine的过程很简洁,非常适合多主机环境.除此之外 ...

  9. IDLE的使用

    为什么要用IDE? 到现在为止,我们也是写过代码的人啦,但你有没有发现,每次写代码要新建文件.写完保存时还要选择存放地点,执行时还要切换到命令行调用python解释器,好麻烦呀,能否一气呵成,让我简单 ...

  10. mysql数据库----索引补充

    1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2.索引种类 普通索引:仅加速查询 唯一索引:加速查询 + 列值唯一(可以有 ...