• codeforces 519E


    题意:

    给一棵树,每次询问给两个点u,v,求到这两个点距离相等的点的个数。(n,q<=1e5)

    题解:

    简单题,考虑u,v所在链,如果奇数条边显然ans=0;

        偶数条边则这两个点的中点x符合条件,考虑链外还有什么点符合条件:中点x连着的其他子树中的点;

        倍增+分类讨论一波;

    坑点:u==v时的情况

     1 #include<bits/stdc++.h>
     2 #define maxn 100005
     3 using namespace std;
     4 int n,q;
     5 struct edge
     6 {
     7     int to,next;
     8 }e[maxn<<1];
     9 int head[maxn],p;
    10 void addedge(int u,int v)
    11 {
    12     e[++p].to=v;e[p].next=head[u];head[u]=p;
    13 }
    14 int d[maxn],anc[maxn][20],size[maxn];
    15 void dfs(int u,int f)
    16 {
    17     size[u]=1;
    18     d[u]=d[f]+1;anc[u][0]=f;
    19     for(int i=head[u];i;i=e[i].next)
    20     {
    21         int v=e[i].to;
    22         if(v==f)continue;
    23         dfs(v,u);
    24         size[u]+=size[v];
    25     }
    26 }
    27 void predp()
    28 {
    29     for(int j=1;j<=18;++j)
    30         for(int i=1;i<=n;++i)anc[i][j]=anc[anc[i][j-1]][j-1];
    31 }
    32 int lca(int u,int v)
    33 {
    34     if(d[u]<d[v])swap(u,v);
    35     for(int i=18;i>=0;--i)if(d[anc[u][i]]>=d[v])u=anc[u][i];
    36     if(u==v)return u;
    37     for(int i=18;i>=0;--i)if(anc[u][i]!=anc[v][i])u=anc[u][i],v=anc[v][i];
    38     return anc[u][0];
    39 }
    40 int getanc(int x,int k)
    41 {
    42     for(int i=18;i>=0;--i)if(k>=(1<<i))x=anc[x][i],k-=(1<<i);
    43     return x;
    44 }
    45 int main()
    46 {
    47     scanf("%d",&n);
    48     for(int i=1;i<n;++i)
    49     {
    50         int u,v;
    51         scanf("%d%d",&u,&v);
    52         addedge(u,v);
    53         addedge(v,u);
    54     }
    55     dfs(1,0);
    56     predp();
    57     scanf("%d",&q);
    58     while(q--)
    59     {
    60         int u,v;
    61         scanf("%d%d",&u,&v);
    62         int t=lca(u,v);
    63         int dis1=d[u]-d[t],dis2=d[v]-d[t];
    64         int ans;
    65         if(u==v)ans=n;
    66         else if(dis1==dis2)
    67         {
    68             int x=getanc(u,dis1-1);
    69             int y=getanc(v,dis2-1);
    70             ans=n-size[x]-size[y];
    71         }
    72         else
    73         {
    74             if((dis1+dis2)&1)ans=0;
    75             else
    76             {
    77                 int D=(dis1+dis2)/2;
    78                 if(d[u]<d[v])swap(u,v);
    79                 int x=getanc(u,D);
    80                 int y=getanc(u,D-1);
    81                 ans=size[x]-size[y];
    82             }
    83         }
    84         printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    控件与布局
    高性能mysql笔记 第一章 mysql架构
    简单排序——冒泡,选择,插入
    spring boot的默认配置
    nginx配置 负载均衡
    nginx+tomcat反向代理
    fiddler(4)安装--L
    fiddler(3)http协议-响应报文--L
    fiddler(2)http协议-请求报文--L
    Fiddler(1)简介--L
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10447620.html
Copyright © 2020-2023  润新知