codeforces685B

CF685B Kay and Snowflake

题意翻译

输入一棵树,判断每一棵子树的重心是哪一个节点.

题目描述

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 nn nodes. The root of tree has index 11 . Kay is very interested in the structure of this tree.

After doing some research he formed qq queries he is interested in. The ii -th query asks to find a centroid of the subtree of the node v_{i}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 vv is formed by nodes uu , such that node vv is present on the path from uu 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).

输入格式

The first line of the input contains two integers nn and qq ( 2<=n<=3000002<=n<=300000 , 1<=q<=3000001<=q<=300000 ) — the size of the initial tree and the number of queries respectively.

The second line contains n-1n1 integer p_{2},p_{3},...,p_{n}p2,p3,...,pn ( 1<=p_{i}<=n1<=pi<=n ) — the indices of the parents of the nodes from 22 to nn . Node 11 is a root of the tree. It's guaranteed that p_{i}pi define a correct tree.

Each of the following qq lines contain a single integer v_{i}vi ( 1<=v_{i}<=n1<=vi<=n ) — the index of the node, that define the subtree, for which we want to find a centroid.

输出格式

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.

输入输出样例

输入 #1
7 4
1 1 3 3 5 3
1
2
3
5
输出 #1
3
2
3
6

说明/提示

The first query asks for a centroid of the whole tree — this is node 33 . If we delete node 33 the tree will split in four components, two of size 11 and two of size 22 .

The subtree of the second node consists of this node only, so the answer is 22 .

Node 33 is centroid of its own subtree.

The centroids of the subtree of the node 55 are nodes 55 and 66 — both answers are considered correct.

sol:dfs下去,如果有儿子大于sz的一半,答案肯定在那个儿子里,暴力往上爬即可,应该是nlogn的

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
  ll s=0; bool f=0; char ch=' ';
  while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
  while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
  return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
  if(x<0) {putchar('-'); x=-x;}
  if(x<10) {putchar(x+'0'); return;}
  write(x/10); putchar((x%10)+'0');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('
')
const int N=300005,M=600005;
int n,Q,fa[N],sz[N];
int tot=0,Next[M],to[M],head[N];
int ans[N];
inline void Link(int x,int y)
{
    Next[++tot]=head[x]; to[tot]=y; head[x]=tot;
}
inline void presz(int x)
{
//    cout<<"x="<<x<<endl;
    int e;
    sz[x]=1;
    for(e=head[x];e;e=Next[e])
    {
        presz(to[e]); sz[x]+=sz[to[e]];
    }
}
inline void dfs(int x)
{
//    cout<<"x="<<x<<endl;
    int e; ans[x]=x;
    for(e=head[x];e;e=Next[e])
    {
        dfs(to[e]);
        if((sz[to[e]]<<1)>sz[x]) ans[x]=ans[to[e]];
    }
    if(ans[x]!=x) while((((sz[x]-sz[ans[x]])<<1)>sz[x])&&(ans[x]!=x)) ans[x]=fa[ans[x]];
}
int main()
{
    int i,x;
    R(n); R(Q);
    for(i=2;i<=n;i++)
    {
        R(fa[i]); Link(fa[i],i);
    }
    presz(1);
    dfs(1);
    while(Q--)
    {
        R(x); Wl(ans[x]);
    }
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/gaojunonly1/p/11241918.html