LCA(倍增思想) 全WA但找不出错了 QAQ 求助佬佬们 orz
查看原帖
LCA(倍增思想) 全WA但找不出错了 QAQ 求助佬佬们 orz
877156
yyy_Logic楼主2023/8/2 01:52

#include<bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
#define endl '\n'
#define test printf("\ntest\n")
/*······································*/
const int N = 1e5+10;
int dep[N],fa[N][20],sum[N],a[N],n,m;
vector<int> g[N<<1];

inline int read(){
	char c=getchar();
	int x=0,f=1;
	while(c<'0'||c>'9'){
		if(c=='-'){
			f=-1;
		}
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void dfs(int now,int fath){
	dep[now]=dep[fath]+1;
	fa[now][0]=fath;
	int end=log2(dep[now]);
	for(int i=1;i<=end;i++){
		fa[now][i]=fa[fa[now][i-1]][i-1];
	}
	for(int i=0;i<g[now].size();i++){
		int u=g[now][i];
		if(u!=fath){
			sum[u]=sum[now]+a[u];//前缀和=之前所有的前缀和+u点的权值
			dfs(u,now);
		}
	}
}
inline int lca(int maxx,int minn){
	if(dep[maxx]<dep[minn])
		swap(maxx,minn);
	//跳到同一级
	while(dep[maxx]>dep[minn]){
		int t=log2(dep[maxx]-dep[minn]);
		maxx=fa[maxx][t-1];
	}
	if(maxx==minn)
		return maxx;
	//现在一起向上跳,先大步跳再小步跳
	for(int k=log2(dep[maxx])-1;k>=0;k--){
		if(fa[maxx][k]!=fa[minn][k]){
			maxx=fa[maxx][k];
			minn=fa[minn][k];
		}
	}
	//返回其中一个节点的父节点
	return fa[maxx][0];	
}
inline int query(int x,int y){
//	test;
	int LCA=lca(x,y);
	int ans=sum[x]+sum[y]-sum[LCA]*2+a[LCA];
	return ans;
}
void solve()
{
	scanf("%d %d",&n,&m);
	cout<<n<<' '<<m;
	for(int i=1;i<=n-1;i++){
		int x=read(),y=read();
//		int x,y;
//		cin>>x>>y;
		g[x].push_back(y);
		g[y].push_back(x);
//		cout<<x<<' '<<y<<endl;
	}
	for(int i=1;i<=n;i++){
		a[i]=g[i].size();
		sum[i]=g[i].size();
		cout<<a[i]<<' '<<sum[i]<<endl;
	}
	dfs(1,0);//预处理
	//预处理好了,进行询问
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
//		int x,y;
//		cin>>x>>y;
		printf("%d\n",query(x,y));
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int t = 1;
//	cin>>t;
	while(t--) solve();
	return 0;
}

2023/8/2 01:52
加载中...