CF519E
\[LCA到x和LCA到y的距离相等且x,y不是同一个点\\
ans=n-siz[x]-siz[y]\\
LCA到x和LCA到y的距离不相等,且分别为a,b\\
(1)a+b为奇数,a-b一定为奇数\\
(2)a+b偶数,令a>b,a上必有一点的LCA-(a-b)/2到x,y距离相等\\
设这个点为P,以P为根的子树结点-P到x的结点数+1=到x,y距离相等的点数\\
x=y时ans=n
\]
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1e5 + 5;
int n,m,fa[N][20],dep[N],siz[N];
struct edge{int to,next;}e[N<<1]; int head[N],tot;
inline void add(int u,int v){e[++tot] = (edge){v,head[u]}; head[u] = tot;}
void dfs(int x,int f){
fa[x][0] = f; siz[x] = 1;
for(int i = 1;i < 20;++i) fa[x][i] = fa[fa[x][i-1]][i-1];
dep[x] = dep[f] + 1;
for(int i = head[x];i;i = e[i].next){
int v = e[i].to;
if(v == f) continue;
dfs(v,x); siz[x] += siz[v];
}
}
int LCA(int u,int v) {
if(dep[u]>dep[v])
swap(u,v);
for(int i=19;i>=0;i--)
if(dep[fa[v][i]] >= dep[u]) v = fa[v][i];
if(u==v)
return u;
for(int i=19;i>=0;i--) {
if(fa[u][i]==fa[v][i])
continue;
u = fa[u][i];
v = fa[v][i];
}
return fa[u][0];
}
int jump_up(int u,int k) {
int i = 0;
while(k) {
if(k&1) u = fa[u][i];
k>>=1;
i++;
}
return u;
}
inline int read(){
int x = 0;char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x;
}
int main(){
n = read(); int x,y;
for(int i = 1;i < n;++i){
x = read(); y = read();
add(x,y); add(y,x);
}
m = read(); dfs(1,0);
for(int i = 1;i <= m;++i){
x = read(); y = read();
int lca = LCA(x,y);
if(x == y) printf("%d\n",n);
else if(dep[x] == dep[y]){
int a =jump_up(x,dep[x]-dep[lca]-1);
int b = jump_up(y,dep[y]-dep[lca]-1);
printf("%d\n",n - siz[a] - siz[b]);
}
else{
int d = dep[x]+dep[y] -2*dep[lca];
if(d & 1) puts("0");
else {
if(dep[x]>dep[y]) swap(x,y);
int b = jump_up(y,d/2-1);
int a = fa[b][0];
printf("%d\n",siz[a] - siz[b]);
}
}
}
}