• Codeforces 519E A and B and Lecture Rooms


    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
    ");
     62         return;
     63     }
     64     if (x==y){
     65         printf("%d
    ",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
    ",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-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
    ",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 }

     

     

  • 相关阅读:
    如何在android studio 1.0 启动时设置代理【解决WARN
    【转】如何阅读android源码
    【Android】 BroadcastReceiver详解
    如何在Android app中支持多主题
    从源码角度剖析 setContentView() 背后的机制
    【转】Android EditText的使用及值得注意的地方
    【转】Android应用程序打包时,出现错误:"XXX" is not translated in "af" (Afrikaans), "am" (Amharic), "ar" (Arabic).....
    【转】Fragment对用户可见的判断实践,亲测有效
    【转】从java1到java9每个版本都有什么新特性?
    【转】贝塞尔曲线介绍
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5626763.html
Copyright © 2020-2023  润新知