多询问 树上距离A,B相等的点数。
题目
A and B and Lecture Rooms(https://ac.nowcoder.com/acm/problem/110856)
题目大意
给你一棵有n个节点的树。
有m个询问。每次询问给你一个A,B。问树上到A,B节点距离相等的点有多少个。
输入
第一行包含整数n(1 ≤ n ≤ 10^5)。
接下来的n-1线描述了走廊。第i行(1≤ i≤≤ n - 1)包含两个整数ai和bi(1≤ ai, bi≤ n),ai和bi有一条边。
下一行包含整数m(1 ≤ m ≤ 10^5)-查询数。
接下来的m行描述查询。每行包含两个整数A和B(1≤ A, B≤ n)
样例
输入
4
1 2
2 3
2 4
2
1 2
1 3
输出
0
2
输出
对于每个询问输出有多少个节点到A和B的距离相等。
思路
我们分析如果存在这个点,这个点一定有一个在A-B的路径上。
如果路径长度为奇数就输出0。
如果路径长度为偶数。我们分析:
1.假设A的深度>B的深度
A~B的距离为2k,那么这个点一定是A的第k级祖先C。
可以满足的点就是C的子节点个数-A所在的链的所有节点(就是A的k-1祖先(4)的子树大小)。
2.假设假设A的深度=B的深度
这个就是
#include <bits/stdc++.h>
using namespace std;
vector<int> G[500005];
struct LCA{
int d[500005], fa[500005][22], lg[500005], siz[500005];
void init(int n, int root){//预处理
for(int i = 1; i <= n; ++i){
lg[i] = lg[i-1] + (1 << lg[i-1] == i);
}
dfs(root, 0);
}
void dfs(int now, int father){
fa[now][0]=father; d[now]=d[father]+1; siz[now]=1;
for(int i=1; i<=lg[d[now]]; ++i){
fa[now][i]=fa[fa[now][i-1]][i-1];
}
for(auto x: G[now]){
if(x!=father){
dfs(x, now); siz[now]+=siz[x];
}
}
}
int lca(int x, int y){//LCA
if(d[x]<d[y]) swap(x, y);
while(d[x]>d[y]){
x=fa[x][lg[d[x]-d[y]]-1];
}
if(x==y) return x;
for(int k=lg[d[x]]-1; k>=0; --k){
if(fa[x][k]!=fa[y][k]){
x=fa[x][k], y=fa[y][k];
}
}
return fa[x][0];
}
int dis(int a, int b){
return d[a]+d[b]-2*d[lca(a, b)];
}
int getk(int f, int k){
for(int i=20; i>=0; i--){
if(k&(1<<i)){
f=fa[f][i];
}
}
return f;
}
}lca;
int main(){
int n, m, x, y;
scanf("%d", &n);
for(int i=2; i<=n; i++){
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
lca.init(n, 1);
scanf("%d", &m);
while(m--){
scanf("%d%d", &x, &y);
int dis=lca.dis(x, y);
if(x==y){
printf("%d\n", n);
continue;
}
if(dis%2){
printf("%d\n", 0);
}
else{
dis/=2;
int f, ans=0;
if(lca.d[x]<lca.d[y]){
f=lca.getk(y, dis-1);
ans=lca.siz[lca.fa[f][0]]-lca.siz[f];
}
else if(lca.d[x]>lca.d[y]){
f=lca.getk(x, dis-1);
ans=lca.siz[lca.fa[f][0]]-lca.siz[f];
}
else{
int fa=lca.getk(x, dis-1);
int fb=lca.getk(y, dis-1);
ans=n-lca.siz[fa]-lca.siz[fb];
}
printf("%d\n", ans);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)