题意:有50中权值,然后让你求树上的链的权值
思路:直接倍增LCA套一下就行了
代码:
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=300000+7; const LL MOD=998244353; LL qmod(LL a, LL b) { if (b == 0) return 1; LL r = a % MOD; LL k = 1; while (b > 1){ if ((b & 1)!=0) k = (k * r) % MOD; r = (r * r) % MOD; b >>= 1; } return (r * k) % MOD; } int n,m,s,num; int f[maxn][30],head[maxn],dep[maxn]; bool vis[maxn]; LL val[maxn][60]; struct node { int next,to; }e[maxn<<1]; inline void add(int from,int to) { e[++num].next=head[from]; e[num].to=to; head[from]=num; } inline void dfs(int x,int d,int pre) { vis[x]=1;dep[x]=d; for(int i=1;i<=55;i++){ val[x][i]=(val[pre][i]+qmod(dep[x]-1,i))%MOD; // printf("fuck rt==%d i==%d dep[x]==%d val==%lld\n",x,i,dep[x]-1,val[x][i]); } for(int i=head[x];i;i=e[i].next) { int to=e[i].to; if(!vis[to]) { f[to][0]=x; dfs(to,d+1,x); } } } inline int lca(int a,int b) { if(dep[a]<dep[b]){int t=a;a=b;b=t;} int d=dep[a]-dep[b]; for(int i=20;i>=0;i--) if(d&(1<<i)) a=f[a][i]; if(a==b) return a; for(int i=20;i>=0;i--) if(f[a][i]!=f[b][i]) { a=f[a][i]; b=f[b][i]; } return f[a][0]; } int main() { n=read(); for(int i=1;i<n;i++){ int u=read(),v=read(); add(u,v); add(v,u); } dep[0]=1; dfs(1,1,0); for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; m=read(); while(m--){ int u=read(),v=read(),k=read(); int fa=lca(u,v); LL qw=qmod(dep[fa]-1,k); // printf("test %lld %lld %lld\n",val[u][k],val[v][k],val[fa][k]); LL ans=(val[u][k]+val[v][k]-val[fa][k]-val[fa][k]+qw+MOD+MOD)%MOD; printf("%lld\n",ans%MOD); // printf("test %d--%d fa==%d\n",u,v,lca(u,v)); } return 0; } /* 7 1 2 1 3 2 4 2 5 3 6 3 7 5 1 2 1 3 2 4 2 5 */