一眼看上去LCA+暴力,emm30分,弃疗
然后发现这道题不用修改,也就是说我们可以提前预处理出所有的pow(i,k),我们定义po[i][k]表示i在k次方意义下的前缀和,也就是说从根到i在k次方意义下的前缀和,然后后面取出的时候,要减去不在u->v路径上的部分,直接查表就好
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=998244353;
const int M=300500;
int n,m;
int dep[M],f[M][21];
long long int po[M][55];
vector<int>v[M];
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
return x;
}
inline long long int fpow(long long int a,long long int b)
{
long long int ans=1;
for (;b;a=(a*a)%mod,b>>=1)
if (b&1) ans=(ans*a)%mod;
return ans%mod;
}
inline void dfs(int x,int fa)
{
dep[x]=dep[fa]+1;f[x][0]=fa;
for (int i=1;i<=50;i++)
po[x][i]=(po[fa][i]+fpow(dep[x],i));
for (int i=0;i<v[x].size();i++)
{
int go=v[x][i];
if (go!=fa) dfs(go,x);
}
return ;
}
inline void getf()
{
for (int j=1;j<=20;j++)
for (int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
return ;
}
inline int LCA(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
for (int i=20;i>=0;i--)
if (dep[f[x][i]]>=dep[y])
x=f[x][i];
if (x==y) return x;
for (int i=20;i>=0;i--)
if (f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int main()
{
n=read();int x,y,z;
for (int i=1;i<n;i++)
{
x=read(),y=read();
v[x].push_back(y);
v[y].push_back(x);
}
dep[1]=-1;dfs(1,1);getf();m=read();
for (int i=1;i<=m;i++)
{
x=read();y=read();z=read();
int lca=LCA(x,y);
printf("%lld\n",(po[x][z]+po[y][z]-po[lca][z]-po[f[lca][0]][z])%mod);
}
return 0;
}