离了个大谱,人麻了。
查看原帖
离了个大谱,人麻了。
404249
yyhde3301楼主2021/9/11 20:07

由于本人过菜,所以似乎(根本)看不出 bugbug ,在线捉个大佬。

#include<bits/stdc++.h>
#define debug printf("fuck\n")
using namespace std;
typedef long long lng;
const int maxn=3e5+7,lgmaxn=19+1,maxk=50,mod=998244353;
struct edge{int v,nx;}e[2*maxn];
int n,lgn,eh[maxn],ec;
void addedge(int u,int v){e[++ec]=(edge){v,eh[u]};eh[u]=ec;}
int m,k;
lng pow(lng a,lng b){lng c=1;for(;b;b>>=1,a=a*a%mod)if(b&1)c=a*c%mod;return c;}
int prt[maxn][lgmaxn];
lng dp[maxn][maxk+1],pre[maxn][maxk+1];
void init(int u){
	for(int i=1;i<=lgn;++i)
		prt[u][i]=prt[prt[u][i-1]][i-1];
	for(int i=eh[u];i;i=e[i].nx){
		int v=e[i].v;if(v==prt[u][0])continue;
		prt[v][0]=u,dp[v][1]=dp[u][1]+1;
		for(int j=2;j<=maxk;++j)
			dp[v][j]=dp[v][j-1]*dp[v][1]%mod;
		for(int j=1;j<=maxk;++j)
			pre[v][j]=(pre[u][j]+dp[v][j])%mod;
		init(v);
	}
}
int lca(int a,int b){
	if(dp[a]<dp[b])swap(a,b);
	for(int i=lgn;i>=0;--i)
		if(prt[a][i]&&dp[prt[a][i]][1]>=dp[b][1])
			a=prt[a][i];
	if(a==b)return a;
	for(int i=lgn;i>=0;--i)
		if(prt[a][i]!=prt[b][i])
			a=prt[a][i],b=prt[b][i];
	return prt[a][0];
}
lng calc(int a,int b,int k){
	int c=lca(a,b);
	return ((pre[a][k]+pre[b][k]-pre[c][k]-pre[prt[c][0]][k])%mod+mod)%mod;
}
int main(){
	scanf("%d",&n);lgn=ceil(log2(n));
	for(int i=1,x,y;i<n;++i)
		scanf("%d%d",&x,&y),addedge(x,y),addedge(y,x);
	init(1);
	scanf("%d",&m);
	for(int i=1,x,y,z;i<=m;++i)
		scanf("%d%d%d",&x,&y,&z),printf("%lld\n",calc(x,y,z));
	return 0;
}
2021/9/11 20:07
加载中...