预处理,树上差分。注意深度减一
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a)) #define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a)) #define Fill(a,b) memset(a, b, sizeof(a)) #define Max(a,b) ((a) > (b) ? (a) : (b)) #define Min(a,b) ((a) < (b) ? (a) : (b)) #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b)) //#define ON_DEBUGG #ifdef ON_DEBUGG #define D_e_Line printf("\n----------\n") #define D_e(x) cout << (#x) << " : " << x << endl #define Pause() system("pause") #define FileOpen() freopen("in.txt", "r", stdin) #else #define D_e_Line ; #define D_e(x) ; #define Pause() ; #define FileOpen() ; #endif using namespace std; struct ios{ template<typename ATP>inline ios& operator >> (ATP &x){ x = 0; int f = 1; char ch; for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1; while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar(); x *= f; return *this; } }io; const int N = 300007; const int mod = 998244353; #define int long long struct Edge{ int nxt, pre; }e[N << 1]; int head[N], cntEdge; inline void add(int u, int v){ e[++cntEdge] = (Edge){ head[u], v}, head[u] = cntEdge; } int maxDep; int fa[N], son[N], dep[N], siz[N]; inline void DFS_First(int u, int father){ dep[u] = dep[father] + 1, fa[u] = father, siz[u] = 1; maxDep = Max(maxDep, dep[u]); //re define maxDep for(register int i = head[u]; i; i = e[i].nxt){ int v = e[i].pre; if(v == father) continue; DFS_First(v, u); siz[u] += siz[v]; if(!son[u] || siz[v] > siz[son[u]]){ son[u] = v; } } } int top[N], rnk[N], dfn[N], dfnIndex; inline void DFS_Second(int u, int ancester){ top[u] = ancester, dfn[u] = ++dfnIndex, rnk[dfnIndex] = u; if(!son[u]) return; DFS_Second(son[u], ancester); for(register int i = head[u]; i; i = e[i].nxt){ int v = e[i].pre; if(v != son[u] && v != fa[u]) DFS_Second(v, v); } } int val[51][N], p[N][51]; inline int Query(int x, int y, int K){ int sum = 0; while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) Swap(x, y); sum = (sum + val[K][dfn[x]] - val[K][dfn[top[x]] - 1] + mod) % mod; x = fa[top[x]]; } //D_e(sum); if(dep[x] < dep[y]) Swap(x, y); return (sum + val[K][dfn[x]] - val[K][dfn[y] - 1] + mod) % mod; } #undef int int main(){ #define int long long FileOpen(); int n; io >> n; R(i,2,n){ int u, v; io >> u >> v; add(u, v); add(v, u); } DFS_First(1, 0); DFS_Second(1, 1); --maxDep; R(i,1,n) --dep[i]; // !!!!!! R(i,1,maxDep){ p[i][1] = i; R(k,2,50){ p[i][k] = p[i][k - 1] * i % mod; //D_e(p[i][k]); } } R(k,1,50){ R(i,1,n){ val[k][i] = (val[k][i - 1] + p[dep[rnk[i]]][k]) % mod;//, D_e(val[k][i]); } } int Ques; io >> Ques; while(Ques--){ int x, y, K; io >> x >> y >> K; printf("%lld\n", Query(x, y, K)); } return 0; }