列表

详情


NC235654. 牛可乐和公平点

描述

牛可乐得到了一张有 n 个点的地图。这 n 个点之间由 n-1 条边连接,从任意一个点出发都可以到达其余点中的任意一个。

牛可乐定义“公平点”是对于给定的点 i 和点 j,“公平点”到点 i 的距离和到点 j 的距离相同,两点之间的距离是两点间最短路径的边数。

牛可乐想请你计算出,对于给定的两个点,有多少公平点呢?

输入描述

第一行包含一个整数 

之后 n-1 行,每行包含两个整数 ,代表 uv 两点之间存在一条边。

行包含一个整数 ,代表询问次数。

之后 q 行,每行包含两个整数 ,代表一组询问的两个点。

输出描述

对于每组询问,输出一行一个整数,代表对于给定的两点,“公平点”的数量。

示例1

输入:

4
1 2
2 3
2 4
2
1 2
1 3

输出:

0
2

说明:

对于第一组询问,没有点到 节点1 和节点 2 的距离相等。答案为 0

对于第二组询问,节点 2 到节点 1,3 的距离均为 1,节点 4 到节点 1,3 的距离均为 2。故答案为 2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 635ms, 内存消耗: 51756K, 提交时间: 2023-07-09 21:38:37

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
ll dep[1010000],n,fa[1010000][22],lg[1010000];
ll sum[1010000],s1,s2;
int q;
vector<ll> p[1010000];
void dfs(ll now,ll bef)
{
	dep[now]=dep[bef]+1;
	fa[now][0]=bef;
	for(ll i=1;i<=20;i++)
	fa[now][i]=fa[fa[now][i-1]][i-1];
	for(ll i=0;i<p[now].size();i++)
	{
		ll tp=p[now][i];
		if(tp==bef) continue;
		dfs(tp,now);
		sum[now]+=sum[tp];
	}
	sum[now]++;
}
ll LCA(ll x,ll y)
{
	if(dep[x]<dep[y]) swap(x,y);
	while(dep[x]>dep[y])
	x=fa[x][lg[dep[x]-dep[y]]-1];
	if(x==y) return x;
	for(ll i=lg[dep[x]];i>=0;i--)
	if(fa[x][i]!=fa[y][i])
	x=fa[x][i],y=fa[y][i];
	
	return fa[x][0];
}
int main()
{
	cin>>n;
	for(ll i=1;i<n;i++)
	{
		ll x,y;
		cin>>x>>y;
		p[x].push_back(y);
		p[y].push_back(x);
	}
	for(ll i=1;i<=n;i++)
	lg[i]=lg[i-1]+(1<<lg[i-1]==i);
	dfs(1,0);
	cin>>q;
	for(ll i=1;i<=q;i++)
	{
		ll x,y;
		cin>>x>>y;
		if(x==y) cout<<n<<endl;
		else if((abs(dep[x]-dep[y]))%2==1) cout<<0<<endl;
		else
		{
			ll t=LCA(x,y);
			if(dep[x]==dep[y])
			{
				ll s1=x,s2=y;
				for(ll i=20;i>=0;i--)
					if(dep[fa[s1][i]]>dep[t])
						s1=fa[s1][i];
				for(ll i=20;i>=0;i--)
					if(dep[fa[s2][i]]>dep[t])
						s2=fa[s2][i];
				ll ans=0;
				cout<<n-sum[s1]-sum[s2]<<endl;
			}
			else
			{
				if(dep[x]<dep[y]) swap(x,y);
				ll hr=(dep[x]-dep[y])/2;
				ll want=dep[t]+hr;
				ll s1=x;
				for(ll i=20;i>=0;i--)
					if(dep[fa[s1][i]]>want)
						s1=fa[s1][i];
				t=fa[s1][0];
				cout<<sum[t]-sum[s1]<<endl;
			}
		}
	}
}

上一题