codeforces div294 E 求到树上两点距离相同点的数目
很显然的lca树上倍增问题
1.两个点是相同点ans=n
2.两个点深度相同ans=n-size 包含x子树-size 包含y子树
3.两个点深度不同:则ans=深的那个向上走step/2步的size-向上走step/2-1的size
然后用倍增写啦==额我的solve函数好丑
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int parent[200005][25]; 6 int now=0,next[200005],point[200005],head[200005]; 7 int depth[200005],size[200005]; 8 void add(int x,int y) 9 { 10 next[++now]=head[x]; 11 head[x]=now; 12 point[now]=y; 13 } 14 void dfs(int u,int pre,int deep) 15 { 16 parent[u][0]=pre; 17 depth[u]=deep; 18 size[u]=1; 19 for (int i=head[u];i;i=next[i]) 20 { 21 int v=point[i]; 22 if (v==pre) continue; 23 dfs(v,u,deep+1); 24 size[u]+=size[v]; 25 } 26 } 27 void double_build(int n) 28 { 29 int i,j; 30 for (i=0;i<=20;i++) 31 for (j=1;j<=n;j++) 32 if (parent[j][i]<=0) parent[j][i+1]=0; 33 else parent[j][i+1]=parent[parent[j][i]][i]; 34 } 35 int go_up(int u,int deep) 36 { 37 for (int k=0;k<=20;k++) 38 if ((deep>>k)&1) u=parent[u][k]; 39 return u; 40 } 41 int solve(int n,int u,int v) 42 { 43 int i,step=0,x=u,y=v,f1,f2,f3,f4,judge=0; 44 if (depth[u]>depth[v]) swap(u,v),swap(x,y); 45 for (i=0;i<=20;i++) 46 if ((depth[v]-depth[u])>>i&1) 47 { 48 judge=1; 49 step-=depth[parent[v][i]]-depth[v]; 50 v=parent[v][i]; 51 } 52 if (u==v){ 53 if (step%2) return 0; 54 f1=go_up(y,step/2); 55 f2=go_up(y,step/2-1); 56 return size[f1]-size[f2]; 57 } 58 for (i=20;i>=0;i--) 59 if (parent[u][i]!=parent[v][i]) 60 { 61 step-=2*(depth[parent[u][i]]-depth[u]); 62 u=parent[u][i]; 63 v=parent[v][i]; 64 } 65 step+=2; 66 if (step%2) return 0; 67 if (judge==0) 68 { 69 f2=go_up(y,step/2-1); 70 f3=go_up(x,step/2-1); 71 return n-size[f2]-size[f3]; 72 } 73 f1=go_up(y,step/2); 74 f2=go_up(y,step/2-1); 75 return size[f1]-size[f2]; 76 } 77 int main() 78 { 79 int n,x,y,i,m; 80 scanf("%d",&n); 81 memset(head,0,sizeof(head)); 82 for (i=1;i<n;i++) 83 { 84 scanf("%d%d",&x,&y); 85 add(x,y); add(y,x); 86 } 87 dfs(1,0,0); 88 double_build(n); 89 scanf("%d",&m); 90 while (m--) 91 { 92 scanf("%d%d",&x,&y); 93 if (x==y) printf("%d\n",n); 94 else printf("%d\n",solve(n,x,y)); 95 } 96 return 0; 97 }