N = getnum (), Q = getnum (); for (int i = 1; i <= N; i ++) a[i] = getnum (), b[i] = getnum (); sum[0][0] = 1, inv[0][0] = 1; for (int i = 1; i <= N; i ++) mul (sum[i], sum[i - 1], i); inverse (sum[N], inv[N]); for (int i = N - 1; i >= 1; i --) mul (inv[i], inv[i + 1], i + 1); for (int i = 0; i <= N; i ++) for (int j = 1; j <= C; j ++) inv[i][j] = (inv[i][j] + inv[i][j - 1]) % MOD; for (int q = 1; q <= Q; q ++) { int l = getnum (), r = getnum (), V = getnum (); l = (l + ans) % N + 1, r = (r + ans) % N + 1; if (l > r) swap (l, r); ans = 0; for (int i = 0; i <= V; i ++) ans = (ans + 1ll * sum[r][i] * inv[l - 1][V - i] % MOD) % MOD; printf ("%d\n", ans); }
inlineintpower(int x, int p){ int cnt = 1; while (p) { if (p & 1) cnt = 1ll * cnt * x % MOD; x = 1ll * x * x % MOD; p >>= 1; } return cnt; } constint inv2 = power (2, MOD - 2);
structLFS {int to, next; } ; LFS Link[MAXM << 1]; int Head[MAXN]= {0}, size = 0; voidInsert(int u, int v){ Link[++ size].to = v; Link[size].next = Head[u];
Head[u] = size; }
int T, N;
int len[MAXN]= {0}, son[MAXN]; voidDFS(int root, int father){ len[root] = 0, son[root] = - 1; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father) continue; DFS (v, root); if (son[root] == - 1 || len[v] > len[son[root]]) son[root] = v; } if (~ son[root]) len[root] = len[son[root]] + 1; } int tmp[MAXN << 1], *dp[MAXN], *id; int mul[MAXN], imul[MAXN], add[MAXN], g[MAXN], ig[MAXN]; int lim[MAXN], zero[MAXN]= {0}; intf(int n, int k){ k = min (k, len[n]); if (lim[n] <= k) return (1ll * zero[n] * mul[n] % MOD + add[n]) % MOD; return (1ll * dp[n][k] * mul[n] % MOD + add[n]) % MOD; } intdf(int n, int r){ return1ll * (1ll * r - add[n] + MOD) % MOD * imul[n] % MOD; } voidDP(int u, int fa){ if (son[u] == - 1) { mul[u] = imul[u] = 1; add[u] = g[u] = 2; lim[u] = N + 1, ig[u] = inv2; return ; } dp[son[u]] = dp[u] + 1; DP (son[u], u); mul[u] = mul[son[u]], imul[u] = imul[son[u]], add[u] = add[son[u]]; lim[u] = lim[son[u]], zero[u] = zero[son[u]]; dp[u][0] = df (u, 1); for (int i = Head[u]; i; i = Link[i].next) { int v = Link[i].to; if (v == fa || v == son[u]) continue; dp[v] = id, id += len[v] + 1, DP (v, u); for (int j = 1; j <= len[v] + 1; j ++) { if (lim[u] == j) dp[u][j] = zero[u], lim[u] ++; dp[u][j] = df (u, 1ll * f (u, j) * f (v, j - 1) % MOD); } if (! g[v]) { lim[u] = len[v] + 2, zero[u] = df (u, 0); continue; } mul[u] = 1ll * mul[u] * g[v] % MOD; imul[u] = 1ll * imul[u] * ig[v] % MOD; add[u] = 1ll * add[u] * g[v] % MOD; for (int j = 0; j <= len[v] + 1; j ++) dp[u][j] = df (u, 1ll * f (u, j) * ig[v] % MOD) % MOD; } add[u] = (1ll * add[u] + 1) % MOD; if (son[fa] != u) { g[u] = f (u, len[u]); ig[u] = power (g[u], MOD - 2); } } int gr[MAXN]= {0}; voidstati(int u, int fa){ gr[u] = 1; for (int i = Head[u]; i; i = Link[i].next) { int v = Link[i].to; if (v == fa) continue; stati (v, u); gr[u] = 1ll * gr[u] * (gr[v] + 1) % MOD; } } int subpro[MAXN], subflo[MAXN]; voidinit(){ memset (Head, 0, sizeof (Head)), size = 0; memset (tmp, 0, sizeof (tmp)); id = tmp; for (int i = 0; i <= N; i ++) { mul[i] = imul[i] = add[i] = lim[i] = zero[i] = g[i] = ig[i] = 0; subpro[i] = subflo[i] = 1; } } voidsolve(){ DFS (1, 0); dp[1] = id, id += len[1] + 1; for (int i = Head[1]; i; i = Link[i].next) { int v = Link[i].to; dp[v] = id, id += len[v] + 1; DP (v, 1); for (int j = 0; j <= len[v]; j ++) subpro[j] = 1ll * subpro[j] * f (v, j) % MOD; if (len[v] + 1 <= len[1]) subflo[len[v] + 1] = 1ll * subflo[len[v] + 1] * f (v, len[v]) % MOD; } for (int i = 1; i <= len[1]; i ++) subflo[i] = 1ll * subflo[i - 1] * subflo[i] % MOD; for (int i = 0; i <= len[1]; i ++) subpro[i] = 1ll * subpro[i] * subflo[i] % MOD; stati (1, 0); int ans = gr[1]; for (int i = Head[1]; i; i = Link[i].next) { int v = Link[i].to; for (int j = 0; j <= len[v]; j ++) { int del = (1ll * f (v, j) - (j > 0 ? f (v, j - 1) : 1) + MOD) % MOD; if (j > 0) del = 1ll * del * subpro[j - 1] % MOD * power (f (v, j - 1), MOD - 2) % MOD; ans = (1ll * ans - del + MOD) % MOD; } } printf ("%d\n", ans); }
inlineintgetnum(){ int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
intmain(){ T = getnum (); for (int Case = 1; Case <= T; Case ++) { N = getnum (); init (); for (int i = 1; i < N; i ++) { int u = getnum (), v = getnum (); Insert (u, v), Insert (v, u); } solve (); }