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 ...
 
随机推荐
- Linux安装Vmware Tools/vmtools(通用)
			
以下方法适用于centos/Ubuntu #新建一个临时目录,用于挂载光驱 mkdir /tmp/cdrom mount -t iso9660 /dev/cdrom /tmp/cdrom cp -r ...
 - ansible加速不管用
			
ansible加速 试过不管用,反而更慢 cat > /root/.ssh/config <<EOF Host * Compression yes ServerAliveInterv ...
 - 走进Selenium新世界
			
浏览器 Firefox Setup 35.0.1 安装完成后设置菜单栏 关闭浏览器自动更新 插件配置(必备武器) FireBug Firebug是firefox下的一个扩展,能够调试所有网站语言,如H ...
 - DataTable.Select筛选过滤数据返回DataRow[]转为DataTable添加到DataSet
			
问题还原,如图所示,我们要筛选所有SHDP 为北京翠微KR的数据. 1. 筛选DataTable微软为我们提供了一个方法DataTable.Select(),其用法如下: 1) Select()—— ...
 - mysql事件(event)
			
[小结]简单案例 SET GLOBAL event_scheduler=1delimiter $$ create definer = current_user event `test`.`event_ ...
 - HanLP-实词分词器详解
			
在进行文本分类(非情感分类)时,我们经常只保留实词(名.动.形)等词,为了文本分类的分词方便,HanLP专门提供了实词分词器类NotionalTokenizer,同时在分类数据集加载处理时,默认使用了 ...
 - myeclipse中jpa的安装以及jpa reverse engining
			
myeclipse中jpa的安装以及jpa reverse engining 安装 右击 Configure Facets, Install JPA jpa reverse engining 1.db ...
 - [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)
			
[BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...
 - Laravel-admin form 表单是增加或者修改
			
Laravel-admin 实现 form 表单是增加或者修改的三种方法,应用情景:1.新增或者修改 form 展示的表单不同:2.新增或者保存前后回调进行其他的操作 1. use Illuminat ...
 - 如何实现一个简化版的 jQuery
			
对于操作 DOM 来说,jQuery 是非常方便的一个库,虽然如今随着 React, Vue 之类框架的流行,jQuery 用得越来越少了,但是其中很多思想还是非常值得我们学习的,这篇文章将介绍如何从 ...