Codeforces 519E A and B and Lecture Rooms

时间:2022-04-19 20:56:31

http://codeforces.com/contest/519/problem/E

题意:

给出一棵树和m次询问,每次询问给出两个点,求出到这两个点距离相等的点的个数。

思路:

lca...然后直接判就好了,挂dp标签的人是什么心态。。

 

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<iostream>
  6 int tot,go[200005],first[200005],next[200005];
  7 int son[200005],fa[200005][19];
  8 int deep[200005];
  9 int n,bin[20];
 10 int read(){
 11     int t=0,f=1;char ch=getchar();
 12     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 13     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
 14     return t*f;
 15 }
 16 void insert(int x,int y){
 17     tot++;
 18     go[tot]=y;
 19     next[tot]=first[x];
 20     first[x]=tot;
 21 }
 22 void add(int x,int y){
 23     insert(x,y);insert(y,x);
 24 }
 25 void dfs(int x,int f){
 26     son[x]=1;
 27     for (int i=1;i<=18;i++)
 28      fa[x][i]=fa[fa[x][i-1]][i-1];
 29     for (int i=first[x];i;i=next[i]){
 30         int pur=go[i];
 31         if (pur==f) continue;
 32         deep[pur]=deep[x]+1;
 33         fa[pur][0]=x;
 34         dfs(pur,x);
 35         son[x]+=son[pur];
 36     }
 37 }
 38 int lca(int x,int y){
 39     if (deep[x]<deep[y]) std::swap(x,y);
 40     int t=deep[x]-deep[y];
 41     for (int i=0;i<=18;i++)
 42      if (t&bin[i])
 43       x=fa[x][i];
 44     if (x==y) return x;
 45     for (int i=18;i>=0;i--)
 46      if (fa[x][i]!=fa[y][i])
 47       x=fa[x][i],y=fa[y][i];
 48     if (x==y) return x;
 49     else return fa[x][0];  
 50 }
 51 void up(int &x,int dep){
 52     int t=deep[x]-dep;
 53     for (int i=0;i<=18;i++)
 54      if (t&bin[i])
 55       x=fa[x][i];  
 56 }
 57 void work(int x,int y){
 58     int t=lca(x,y);
 59     int len=deep[x]-deep[t]+1+deep[y]-deep[t]+1-1;
 60     if (len%2==0){
 61         printf("0\n");
 62         return;
 63     }
 64     if (x==y){
 65         printf("%d\n",n);
 66         return;
 67     }
 68     if (t==x||t==y){
 69         if (t==x) std::swap(x,y);
 70         int tt=x;
 71         up(tt,deep[tt]-len/2);
 72         up(x,deep[tt]+1);
 73         printf("%d\n",son[tt]-son[x]);
 74     }else{
 75         if (deep[x]<deep[y]) std::swap(x,y);
 76         if (deep[x]==deep[y]){
 77             up(x,deep[t]+1);
 78             up(y,deep[t]+1);
 79             printf("%d\n",n-son[x]-son[y]);
 80         }else{
 81             int tt=x;
 82             up(tt,deep[tt]-len/2);
 83             up(x,deep[tt]+1);
 84             printf("%d\n",son[tt]-son[x]);
 85         }
 86     }
 87 }
 88 int main(){
 89     n=read();bin[0]=1;for (int i=1;i<=18;i++) bin[i]=bin[i-1]*2;
 90     for (int i=1;i<n;i++){
 91         int x=read(),y=read();
 92         add(x,y);
 93     }
 94     dfs(1,0);
 95     int T=read();
 96     while (T--){
 97         int x=read(),y=read();
 98         work(x,y);
 99     }
100     return 0;
101 }