• 【CF686D】Kay and Snowflake(树的重心)


    题意:给定一棵n个点的树,q次询问,每次询问以某个点为根的子树编号是多少

    n,q<=3e5

    思路:设sz[u]为以u为根子树的size,v为u的size最大的儿子

    若sz[v]*2<sz[u]则u即为重心

    否则重心在以v为根的重心到u的路径上,暴力往上走,可以证明是均摊O(n)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef unsigned int uint;
     5 typedef unsigned long long ull;
     6 typedef long double ld;
     7 typedef pair<int,int> PII;
     8 typedef pair<ll,ll> Pll;
     9 typedef vector<int> VI;
    10 typedef vector<PII> VII;
    11 typedef pair<ll,ll>P;
    12 #define N  500010
    13 #define M  1000000
    14 #define INF 1e9
    15 #define fi first
    16 #define se second
    17 #define MP make_pair
    18 #define pb push_back
    19 #define pi acos(-1)
    20 #define mem(a,b) memset(a,b,sizeof(a))
    21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
    22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
    23 #define lowbit(x) x&(-x)
    24 #define Rand (rand()*(1<<16)+rand())
    25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
    26 #define ls p<<1
    27 #define rs p<<1|1
    28 #define fors(i) for(auto i:e[x]) if(i!=p)
    29 
    30 const int MOD=1e9+7,inv2=(MOD+1)/2;
    31       double eps=1e-6;
    32       int dx[4]={-1,1,0,0};
    33       int dy[4]={0,0,-1,1};
    34 
    35 int head[N],vet[N],nxt[N],fa[N],sz[N],ans[N],f[N],tot;
    36 
    37 int read()
    38 {
    39    int v=0,f=1;
    40    char c=getchar();
    41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
    42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
    43    return v*f;
    44 }
    45 
    46 void add(int a,int b)
    47 {
    48     nxt[++tot]=head[a];
    49     vet[tot]=b;
    50     head[a]=tot;
    51 }
    52 
    53 void dfs(int u)
    54 {
    55     int e=head[u];
    56     ans[u]=u;
    57     sz[u]=1;
    58     int mx=0,t=0;
    59     while(e)
    60     {
    61         int v=vet[e];
    62         dfs(v);
    63         sz[u]+=sz[v];
    64         if(sz[v]>mx)
    65         {
    66             mx=sz[v];
    67             t=v;
    68         }
    69         e=nxt[e];
    70     }
    71     f[u]=mx;
    72     if(f[u]*2<sz[u]) ans[u]=u;
    73      else
    74      {
    75          int now=ans[t];
    76          while(fa[now]&&max(f[now],sz[u]-sz[now])>max(f[fa[now]],sz[u]-sz[fa[now]])) now=fa[now];
    77          ans[u]=now;
    78      }
    79 }
    80 
    81 int main()
    82 {
    83     int n=read(),q=read();
    84     rep(i,1,n) head[i]=0;
    85     tot=0;
    86     rep(i,2,n)
    87     {
    88         fa[i]=read();
    89         add(fa[i],i);
    90     }
    91     dfs(1);
    92     rep(i,1,q)
    93     {
    94         int x=read();
    95         printf("%d
    ",ans[x]);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    修改mysql密码的四种方法
    phpcms模板生成原理
    如何给虚拟主机安装phpMyAdmin
    如何修改数据库密码
    web 服务器、PHP、数据库、浏览器是如何实现动态网站的
    编写shell时,提示let/typeset:not found
    Linux下采用VI编辑器删除复制或移动多行文本内容
    BASH 学习笔记小结
    list容器的C++代码实现
    Groovy入门教程
  • 原文地址:https://www.cnblogs.com/myx12345/p/11792530.html
Copyright © 2020-2023  润新知