codeforces 519E A and B and Lecture Rooms

题意:

给一棵树,每次询问给两个点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\n",ans);
85     }
86     return 0;
87 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/10447620.html
今日推荐