BZOJ 3572 世界树
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
2 1
3 2
4 3
5 4
6 1
7 3
8 3
9 4
10 1
5
2
61
5
2 7 3 6 9
1
8
4
8 7 10 3
5
2 9 3 5 8
Sample Output
3 1 4 1 1
1 0
1 1 3 5
4 1 3 1 1
HINT
N<=300000, q<=300000,m[1]+m[2]+…+m[q]<=300000
Source
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<cstdlib>
- #include<algorithm>
- using namespace std;
- #define maxn 300010
- int side[maxn],next[maxn*],f[maxn][],tmp[maxn],stack[maxn],DFN;
- int toit[maxn*],dfn[maxn],dep[maxn],ask[maxn],size[maxn],tree[maxn],cnt,n;
- int ans[maxn],father[maxn],val[maxn],in[maxn]; pair <int,int> near[maxn];
- inline bool cmp(int a,int b) { return dfn[a] < dfn[b]; }
- inline void add(int a,int b) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; }
- inline void ins(int a,int b) { add(a,b); add(b,a); }
- inline void dfs(int now)
- {
- dfn[now] = ++DFN;
- for (int i = ;( << i)<=dep[now];++i) f[now][i] = f[f[now][i-]][i-];
- for (int i = side[now];i;i = next[i])
- if (toit[i]!=f[now][])
- {
- f[toit[i]][] = now; dep[toit[i]] = dep[now]+;
- dfs(toit[i]);size[now] += size[toit[i]]; }
- size[now]++;
- }
- inline void jump(int &a,int step)
- {
- for (int i = ;step;step >>= ,++i)
- if (step&) a = f[a][i];
- }
- inline int lca(int a,int b)
- {
- if (dep[a] < dep[b]) swap(a,b);
- jump(a,dep[a]-dep[b]);
- if (a == b) return a;
- for (int i = ;i >= ;)
- {
- if (f[a][i] != f[b][i]) a = f[a][i],b = f[b][i],++i;
- else --i;
- }
- return f[a][];
- }
- inline int find(int now,int d)
- {
- for (int i = ;i>=&&dep[now]>d;)
- {
- if (dep[f[now][i]] >= d) now = f[now][i],++i;
- else --i;
- }
- return now;
- }
- inline void solve()
- {
- int k; scanf("%d ",&k);
- for (int i = ;i <= k;++i)
- {
- scanf("%d",ask+i),tree[i] = tmp[i] = ask[i];
- near[ask[i]] = make_pair(,ask[i]); ans[ask[i]] = ;
- }
- sort(ask+,ask+k+,cmp);
- int top = ,tot = k;
- for (int i = ;i <= k;++i)
- {
- int p = ask[i];
- if (!top) stack[++top] = p,father[p] = ;
- else
- {
- int x = lca(stack[top],p);
- father[p] = x;
- while (top&&dep[stack[top]] > dep[x])
- {
- if (dep[stack[top-]] <= dep[x])
- father[stack[top]] = x;
- --top;
- }
- if (stack[top] != x)
- {
- father[x] = stack[top]; tree[++tot] = x;
- stack[++top] = x; near[x] = make_pair(<<,);
- }
- stack[++top] = p;
- }
- }
- sort(tree+,tree+tot+,cmp);
- for (int i = ;i <= tot;++i)
- {
- int p = tree[i]; val[p] = size[p];
- if (i > ) in[p] = dep[p]-dep[father[p]];
- }
- for (int i = tot;i > ;--i)
- {
- int p = tree[i],fa = father[p];
- near[fa] = min(near[fa],make_pair(near[p].first+in[p],near[p].second));
- }
- for (int i = ;i <= tot;++i)
- {
- int p = tree[i],fa = father[p];
- near[p] = min(near[p],make_pair(near[fa].first+in[p],near[fa].second));
- }
- for (int i = ;i <= tot;++i)
- {
- int p = tree[i],fa = father[p],sum = size[find(p,dep[fa]+)]-size[p];
- if (fa == ) ans[near[p].second] += n-size[p];
- else
- {
- val[fa] -= sum+size[p];
- if (near[p].second == near[fa].second)
- ans[near[p].second] += sum;
- else
- {
- int dis = (dep[p]-dep[fa]-near[p].first+near[fa].first)>>;
- if (dis+near[p].first==near[fa].first+dep[p]-dep[fa]-dis&&near[fa].second<near[p].second)
- --dis;
- int x = find(p,dep[p]-dis);
- ans[near[p].second] += size[x]-size[p];
- ans[near[fa].second] += sum+size[p]-size[x];
- }
- }
- }
- for (int i = ;i <= tot;++i)
- ans[near[tree[i]].second] += val[tree[i]];
- for (int i = ;i <= k;++i) printf("%d ",ans[tmp[i]]);
- puts("");
- }
- int main()
- {
- freopen("3572.in","r",stdin);
- freopen("3572.out","w",stdout);
- scanf("%d",&n);
- for (int i = ;i < n;++i) { int x,y; scanf("%d %d",&x,&y); ins(x,y); }
- dfs();
- int T; scanf("%d",&T);
- while (T--) solve();
- return ;
- }
BZOJ 3572 世界树的更多相关文章
- BZOJ 3572 世界树(虚树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3572 思路:建立虚树,然后可以发现,每条边不是同归属于一端,那就是切开,一半给上面,一半给下面. # ...
- bzoj 3572世界树 虚树+dp
题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...
- BZOJ 3572: [Hnoi2014]世界树
BZOJ 3572: [Hnoi2014]世界树 标签(空格分隔): OI-BZOJ OI-虚数 OI-树形dp OI-倍增 Time Limit: 20 Sec Memory Limit: 512 ...
- bzoj 3572: [Hnoi2014]世界树 虚树 && AC500
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 520 Solved: 300[Submit][Status] ...
- bzoj 3572 [Hnoi2014]世界树(虚树+DP)
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 645 Solved: 362[Submit][Status] ...
- bzoj 3572 [Hnoi2014]世界树——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3572 关于虚树:https://www.cnblogs.com/zzqsblog/p/556 ...
- BZOJ 3572: [Hnoi2014]世界树 虚树 树形dp
https://www.lydsy.com/JudgeOnline/problem.php?id=3572 http://hzwer.com/6804.html 写的时候参考了hzwer的代码,不会写 ...
- BZOJ 3572 【HNOI2014】 世界树
题目链接:世界树 首先看到\(\sum m_i\le 3\times 10^5\)这个条件,显然这道题就需要用虚树了. 在我们构建出虚树之后,就可以用两遍\(dfs\)来求出离每个点最近的议事处了.然 ...
- AC日记——[HNOI2014]世界树 bzoj 3572
3572 思路: 虚树+乱搞: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 300005 #define ...
随机推荐
- MySQL 基础(DDL)
SQL分类 SQL语句主要可以划分为一下3个类别 DDL:数据定义语言,定义数据段.数据库.数据表等 DML :数据操纵语句,用于添加.删除.更新和查询数据库记录 ...
- mac下修改mysql的默认字符集为utf8
1,检查默认安装的mysql的字符集 mysql> show variables like '%char%'; +--------------------------+------------- ...
- SSD -----TLC MLC SLC
SLC缓存什么鬼?TLC评测造假要持续多久 2016.5.5来源:中关村在线 TLC的廉价真的将SSD引入了全面普及的高速公路上,谈到TLC我们更多的理解是TLC的P/E(Program/Erase ...
- Xcode常见报错及解决办法
报错一: 在iOS7的真机运行时,弹出错误:App installation failed. There was an internal API error. 如图 解决办法: 在Xcode -> ...
- android开发之service详解
service作为android的四大组件之一,其重要性可想而知,在开发中,我们经常把一些不需要与用户进行交互的工作放在service中来完成,service运行在后台,这样有些人可能会产生错觉,以为 ...
- 关于javascript dom扩展:Selector API
众多javascript库中最常用的一项功能,就是根据css选择符选择与某个模式匹配的DOM元素.之前由于对javascript的认识较低,对javascript对DOM操作还停留在getElemen ...
- codevs 访问艺术馆
/* codevs 1163 访问艺术馆 红果果的树形dp*/ #include<iostream> #include<cstdio> #include<cstring& ...
- int? 参数是这个的时候 是可以传入null的 而int的就不行
such as pager.CurrentPageIndex = (page != null ? (int)page : 1);
- decimal to hexadecimal,binary and octonary.
Here is a simple algorithm about 'decimal' to 'dexadecimal',and the implementation code: /* Convert ...
- WPF里面的常用笔刷
程序运行效果 <Window x:Class="This_brush.MainWindow" xmlns="http://schemas.microsoft.com ...