Kay and Snowflake CodeForces - 686D (树的重心性质)
After the piece of a devilish mirror hit the Kay's eye, he is no longer interested in the beauty of the roses. Now he likes to watch snowflakes.
Once upon a time, he found a huge snowflake that has a form of the tree (connected acyclic graph) consisting of n nodes. The root of tree has index 1. Kay is very interested in the structure of this tree.
After doing some research he formed q queries he is interested in. The i-th query asks to find a centroid of the subtree of the node vi. Your goal is to answer all queries.
Subtree of a node is a part of tree consisting of this node and all it's descendants (direct or not). In other words, subtree of node v is formed by nodes u, such that node v is present on the path from u to root.
Centroid of a tree (or a subtree) is a node, such that if we erase it from the tree, the maximum size of the connected component will be at least two times smaller than the size of the initial tree (or a subtree).
Input
The first line of the input contains two integers n and q (2 ≤ n ≤ 300 000, 1 ≤ q ≤ 300 000) — the size of the initial tree and the number of queries respectively.
The second line contains n - 1 integer p2, p3, ..., pn (1 ≤ pi ≤ n) — the indices of the parents of the nodes from 2 to n. Node 1 is a root of the tree. It's guaranteed that pi define a correct tree.
Each of the following q lines contain a single integer vi (1 ≤ vi ≤ n) — the index of the node, that define the subtree, for which we want to find a centroid.
Output
For each query print the index of a centroid of the corresponding subtree. If there are many suitable nodes, print any of them. It's guaranteed, that each subtree has at least one centroid.
Example
Input
7 4
1 1 3 3 5 3
1
2
3
5
Output
3
2
3
6
Note
The first query asks for a centroid of the whole tree — this is node 3. If we delete node 3 the tree will split in four components, two of size 1 and two of size 2.
The subtree of the second node consists of this node only, so the answer is 2.
Node 3 is centroid of its own subtree.
The centroids of the subtree of the node 5 are nodes 5 and 6 — both answers are considered correct.
题意:
给你一个含有n个节点的树,并且给你q个询问,每一个询问x,问以x为根的子树中重心是哪个节点?
思路:
利用重心的2个性质:
1、对于一棵树来说,删去该树的重心后,所有的子树的大小不会超过原树大小的二分之一
2、两棵树合并后其新的重心在原两个重心的路径中。
那么我们在dfs树的过程中维护cntson[i]代表以i节点为根的子树大小,
然后在利用cntson可以找到一个子树的重心,在一个节点与其儿子节点为根的子树合并时,在当前维护的重心和儿子节点为根的子树的重心的路径中同样通过性质1来更新出当前的重心即可。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 300010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
std::vector<int> son[maxn];
int cntson[maxn];
int q;
int ans[maxn];
int f[maxn];
void dfs(int x, int pre)
{
cntson[x] = 1;
ans[x] = x;
for (auto y : son[x])
{
if (y != pre)
{
dfs(y, x);
cntson[x] += cntson[y];
}
}
for (auto y : son[x])
{
if (y != pre)
{
if (cntson[y] * 2 > cntson[x])
{
ans[x] = ans[y];
}
}
}
while ((cntson[x] - cntson[ans[x]]) * 2 > cntson[x])
{
ans[x] = f[ans[x]];
}
}
// int num;
int main()
{
//freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
//freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
gg(n);
gg(q);
repd(i, 2, n)
{
int x;
gg(x);
son[x].push_back(i);
f[i] = x;
}
dfs(1, 1);
int x;
repd(i, 1, q)
{
gg(x);
printf("%d\n", ans[x] );
}
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
Kay and Snowflake CodeForces - 686D (树的重心性质)的更多相关文章
- Kay and Snowflake CodeForces - 686D
Kay and Snowflake CodeForces - 686D 题意:给一棵有根树,有很多查询(100000级别的),查询是求以任意一点为根的子树的任意重心. 方法很多,但是我一个都不会 重心 ...
- Kay and Snowflake CodeForces - 685B (重心, 好题)
大意:给定有根树, 求每个子树的重心 我太菜了啊, 只能想到暴力树剖, 然而这就是个B题, 感觉树剖+线段树二分还是挺难写的..... 看了题解发现重心一定在重儿子与根的树链上, 重心最多上跳n-1次 ...
- Codeforces 686 D - Kay and Snowflake
D - Kay and Snowflake 思路: 树的重心 利用重心的一个推论,树的重心必定在子树重心的连线上. 然后利用重心的性质,可知,如果有一颗子树的大小超过整棵树的大小的1/2,那么树的重心 ...
- poj1655 Balancing Act 找树的重心
http://poj.org/problem? id=1655 Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)
Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...
- Codeforces Round #359 (Div. 2) D. Kay and Snowflake 树的重心
题目链接: 题目 D. Kay and Snowflake time limit per test 3 seconds memory limit per test 256 megabytes inpu ...
- codeforces 685B Kay and Snowflake 树的重心
分析:就是找到以每个节点为根节点的树的重心 树的重心可以看这三篇文章: 1:http://wenku.baidu.com/link?url=yc-3QD55hbCaRYEGsF2fPpXYg-iO63 ...
- codeforces 686D D. Kay and Snowflake(dfs)
题目链接: D. Kay and Snowflake time limit per test 3 seconds memory limit per test 256 megabytes input s ...
- Codeforces Round #359 (Div. 2) D. Kay and Snowflake 树DP
D. Kay and Snowflake After the piece of a devilish mirror hit the Kay's eye, he is no longer int ...
随机推荐
- Python——PYQT:控件基本使用
QtGui.QComboBox控件常用函数: .addItem(string) #添加字符串项到Item .addItems(list) #添加列表或元组元素到Item .clear() #清除所有I ...
- 关于Yii的ocracle链接问题
1. http://www.yiiframework.com/extension/oci8pdo/ 2.下载extension包,根据配置可解决.
- Ansible 直接请求远程主机执行命令
ansible -all -i host1.abc.com, -m ping #注意主机名称后面的逗号,就算一台主机也是必须的.多台主机可以用逗号隔开 ansible all -i host1.abc ...
- H5中调起微信这么实现,如果未安装则提示未安装
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- swoole前置基础知识 进程间通信
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量.共享存储.Socket ...
- Python爬虫学习==>第七章:urllib库的基本使用方法
学习目的: urllib提供了url解析函数,所以需要学习正式步骤 Step1:什么是urllib urllib库是Python自带模块,是Python内置的HTTP请求库 包含4个模块: >& ...
- SQL常见面试题(学生表_课程表_成绩表_教师表)
表架构 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师 ...
- 谷歌云SSH开启root密码登陆
废话不多说,开始教程 1.先选择从浏览器打开ssh连接服务器连接登录成功后,输入以下命令 sudo -i #切换到root passwd #修改密码 然后会要求输入新密码,然后再重复一次密码,输入密码 ...
- 使用 docsify 創建自己的 markdown 文檔系統
先來看一下我在碼雲上創建的demo: http://lin1270.gitee.io/nicedoc/#/ GIT自己clone一下: https://gitee.com/lin1270/nicedo ...
- c语言:<tchar.h>
头文件“<tchar.h>”作用就是为了进行ASCII码和UNICODE(wide-character)码的头文件(该头文件由微软提供): 这样我们就可以使用TCHAR.H头文件中的定义的 ...