LL power(LL x, int p){ LL cnt = 1; while (p) { if (p & 1) cnt = cnt * x % MOD; x = x * x % MOD; p >>= 1; } return cnt; }
int N, K;
LL fact[MAXN]= {0}, invfact[MAXN]= {0}; inline LL C(int n, int m){ if (n < m) return0; return fact[n] * invfact[m] % MOD * invfact[n - m] % MOD; } inline LL lucas(int n, int m){ if (n == m) return1; if (n < m) return0; if (n <= MOD && m <= MOD) return C (n, m); return C (n % MOD, m % MOD) * lucas (n / MOD, m / MOD) % MOD; } int n, k; inlineintsym(int y, int p){ return p ? - y - 2 : - y + 2 * k + 2; } // y = - 1 & y = k + 1 inline LL path(int y){ return lucas (2 * n, n + y / 2); }
intmain(){ cin >> N >> K; n = N - 1, k = K - 2; fact[0] = invfact[0] = 1; for (int i = 1; i < MOD; i ++) fact[i] = fact[i - 1] * i % MOD; invfact[MOD - 1] = power (fact[MOD - 1], MOD - 2); for (int i = MOD - 2; i >= 1; i --) invfact[i] = invfact[i + 1] * (i + 1) % MOD; int up = 2 * k + 2, down = - 2, p = 1; LL ans = lucas (2 * n, n); while (true) { if (abs (up) > 2 * n && abs (down) > 2 * n) break; int t = p == 1 ? - 1 : 1; ans = (ans + t * path (up) % MOD + MOD) % MOD; ans = (ans + t * path (down) % MOD + MOD) % MOD; up = sym (up, p), down = sym (down, p ^ 1); p ^= 1; } cout << ans << endl;
structLFS {int to, w, next; } ; LFS Link[MAXM << 1]; int Head[MAXN]= {0}, size = 0; voidInsert(int u, int v, int w){ Link[++ size].to = v; Link[size].w = w; Link[size].next = Head[u];
Head[u] = size; }
int N, M, len;
int subsize[MAXN]= {0}; int dfn[MAXN]= {0}, ord = 0; LL d[MAXN]= {0}; voidDFS(int root, LL dist){ subsize[root] = 1; dfn[root] = ++ ord; d[ord] = dist; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to, w = Link[i].w; DFS (v, dist + w); subsize[root] += subsize[v]; } }
int lim; int bel[MAXN]= {0}, bl[MAXB]= {0}, br[MAXB]= {0}, m = 0; LL mini[MAXB]= {0}, maxi[MAXB]= {0}; int subsum[MAXB][MAXV]= {0}, lazy[MAXB]= {0}; voidmaintain(int i){ mini[i] = LINF, maxi[i] = - LINF; for (int j = bl[i]; j <= br[i]; j ++) { d[j] += lazy[i]; mini[i] = min (mini[i], d[j]); maxi[i] = max (maxi[i], d[j]); } lazy[i] = 0; for (int j = 0; j <= maxi[i] - mini[i]; j ++) subsum[i][j] = 0; for (int j = bl[i]; j <= br[i]; j ++) subsum[i][d[j] - mini[i]] ++; for (int j = 1; j <= maxi[i] - mini[i]; j ++) subsum[i][j] += subsum[i][j - 1]; } voidpushdown(int p){ if (! lazy[p]) return ; for (int i = bl[p]; i <= br[p]; i ++) d[i] += lazy[p]; lazy[p] = 0; } voidbuild(){ for (int i = 1; i <= m; i ++) pushdown (i); LL mi = LINF, ma = - LINF; m = 1; for (int i = 1; i <= N; i ++) { mi = min (mi, d[i]), ma = max (ma, d[i]); if (ma - mi > V || i - br[m - 1] > lim) { bl[m] = br[m - 1] + 1, br[m] = i - 1; mi = ma = d[i]; m ++; } bel[i] = m; } bl[m] = br[m - 1] + 1, br[m] = N; for (int i = 1; i <= m; i ++) maintain (i); } voidmodify(int l, int r, int x){ if (bel[l] + 1 >= bel[r]) { for (int i = l; i <= r; i ++) d[i] += x; maintain (bel[l]); maintain (bel[r]); return ; } for (int i = l; i <= br[bel[l]]; i ++) d[i] += x; maintain (bel[l]); for (int i = bel[l] + 1; i <= bel[r] - 1; i ++) { lazy[i] += x; mini[i] += x, maxi[i] += x; } for (int i = bl[bel[r]]; i <= r; i ++) d[i] += x; maintain (bel[r]); } boolcheck(int l, int r, int k, LL mid){ int cnt = 0; if (bel[l] + 1 >= bel[r]) { for (int i = l; i <= r; i ++) cnt += d[i] <= mid; return cnt >= k; } for (int i = l; i <= br[bel[l]]; i ++) cnt += d[i] <= mid; for (int i = bel[l] + 1; i <= bel[r] - 1; i ++) if (mid - mini[i] >= 0) cnt += subsum[i][min (maxi[i] - mini[i], mid - mini[i])]; for (int i = bl[bel[r]]; i <= r; i ++) cnt += d[i] <= mid; return cnt >= k; } LL query(int l, int r, int k){ pushdown (bel[l]); pushdown (bel[r]); LL left = LINF, right = - LINF; for (int i = bel[l]; i <= bel[r]; i ++) { left = min (left, mini[i]); right = max (right, maxi[i]); } if (left == right) return left; LL ans = left; while (left <= right) { LL mid = (left + right) >> 1; if (check (l, r, k, mid)) { ans = mid; right = mid - 1; } else left = mid + 1; } return ans; }
inlineintgetnum(){ int num = 0; char ch = getchar (); bool isneg = false; while (! isdigit (ch)) { if (ch == '-') isneg = true; ch = getchar (); } while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return isneg ? - num : num; }
intmain(){ N = getnum (), M = getnum (), len = getnum (); lim = sqrt (N); for (int i = 2; i <= N; i ++) { int fa = getnum (), w = getnum (); Insert (fa, i, w); } DFS (1, 0); int modi = 0; build (); for (int q = 1; q <= M; q ++) { int opt = getnum (), x = getnum (), k = getnum (); if (opt == 1) { if (subsize[x] < k) { puts ("-1"); continue; } printf ("%lld\n", query (dfn[x], dfn[x] + subsize[x] - 1, k)); } else { modi ++; if (! (modi % 1000)) build (); modify (dfn[x], dfn[x] + subsize[x] - 1, k); } }