inline LL power(LL x, LL p){ LL cnt = 1; while (p) { if (p & 1) cnt = cnt * x % MOD; x = x * x % MOD; p >>= 1; } return cnt; }
int N; constint M = 1e04; int oa[MAXN], ob[MAXN];
LL GCD(LL a, LL b){ return ! b ? a : GCD (b, a % b); } voidexGCD(LL a, LL b, LL& x, LL& y){ if (! b) { x = 1, y = 0; return ; } exGCD (b, a % b, y, x); y -= a / b * x; }
int prime[MAXM]= {0}, pn = 0; voidsepar(int x){ for (int i = 2; i * i <= x; i ++) if (! (x % i)) { prime[++ pn] = i; while (! (x % i)) x /= i; } if (x > 1) prime[++ pn] = x; } int pcnt[2][MAXN][MAXM]= {0}; voidcencus(int p, int id, int x){ for (int i = 1; i <= pn; i ++) if (! (x % prime[i])) { while (! (x % prime[i])) { x /= prime[i]; pcnt[p][id][i] ++; } } }
LL a[MAXM], b[MAXM], c[MAXM], d[MAXM]; boolmerge(){ LL sb = 0, sd = 0; for (int i = 1; i <= pn; i ++) { sb += b[i]; sd += d[i]; } if (! sb && ! sd) { for (int i = 1; i <= pn; i ++) if (a[i] != c[i]) returnfalse; returntrue; } if (! sb || ! sd) { if (! sd) { swap (sb, sd); swap (a, c); swap (b, d); } LL k = - 1; for (int i = 1; i <= pn; i ++) if (d[i]) { if (c[i] > a[i] || (a[i] - c[i]) % d[i]) returnfalse; LL pk = (a[i] - c[i]) / d[i]; if (k != - 1 && pk != k) returnfalse; k = pk; } returntrue; } { int i, j; for (i = 1; i <= pn; i ++) if (sb * d[i] != sd * b[i]) break; if (i <= pn) { for (j = 1; j <= pn; j ++) if (b[i] * d[j] != d[i] * b[j]) // 只有一个解 break; LL ka = d[j] * (c[i] - a[i]) - d[i] * (c[j] - a[j]); LL kb = b[j] * (c[i] - a[i]) - b[i] * (c[j] - a[j]); LL down = d[j] * b[i] - d[i] * b[j]; if (down < 0) ka = - ka, kb = - kb, down = - down; if (ka < 0 || kb < 0 || ka % down || kb % down) returnfalse; ka /= down, kb /= down; for (int k = 1; k <= pn; k ++) { if (a[k] + ka * b[k] != c[k] + kb * d[k]) returnfalse; a[k] = a[k] + ka * b[k], b[k] = 0; } returntrue; } } // ExGCD合并 LL rb = 0, rd = 0, r = 0; for (int i = 1; i <= pn; i ++) if (b[i]) { LL g = GCD (b[i], d[i]); rb = b[i] / g, rd = d[i] / g; if ((a[i] - c[i]) % g) returnfalse; r = (a[i] - c[i]) / g; break; } for (int i = 1; i <= pn; i ++) if (r * (b[i] / rb) != a[i] - c[i]) // 判断是否成比例 returnfalse; if (r < 0) swap (a, c), swap (b, d), swap (rb, rd), r = - r; LL ka, kb; exGCD (rb, rd, ka, kb); ka = (ka * (- r) % rd + rd) % rd; for (int i = 1; i <= pn; i ++) a[i] += ka * b[i], b[i] *= rd; returntrue; }
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(){ N = getnum (); for (int i = 1; i <= N; i ++) oa[i] = getnum (), ob[i] = getnum (); for (int i = 1; i <= N; i ++) separ (oa[i]), separ (ob[i]); sort (prime + 1, prime + pn + 1); pn = unique (prime + 1, prime + pn + 1) - prime - 1; for (int i = 1; i <= N; i ++) cencus (0, i, oa[i]), cencus (1, i, ob[i]); for (int i = 1; i <= pn; i ++) a[i] = pcnt[0][1][i], b[i] = pcnt[1][1][i]; for (int i = 2; i <= N; i ++) { for (int j = 1; j <= pn; j ++) c[j] = pcnt[0][i][j], d[j] = pcnt[1][i][j]; if (! merge ()) { puts ("-1"); return0; } } LL ans = 1; for (int i = 1; i <= pn; i ++) ans = ans * power (prime[i], a[i]) % MOD; cout << ans << endl;
inline 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; } LL pow2[MAXM]= {0};
structLFS {int to, w, next; }; LFS Link[MAXM << 1]; int Head[MAXN]= {0}, sze = 0; voidInsert(int u, int v, int w){ Link[++ sze].to = v; Link[sze].w = w; Link[sze].next = Head[u];
Head[u] = sze; }
LL fact[MAXM]= {0}, invfact[MAXM]= {0}; LL inv[MAXM]= {0}; inline LL C(int n, int m){ return fact[n] * invfact[m] % MOD * invfact[n - m] % MOD; }
int N, M; LL X; structEdge { int u, v, w; Edge (int u = 0, int v = 0, int w = 0) : u (u), v (v), w (w) {} booloperator < (const Edge& p) const { return w < p.w; } } ; Edge edge[MAXM];
int fa[MAXN]= {0}; intfind(int x){ return fa[x] == x ? x : fa[x] = find (fa[x]); } LL Kruskal(){ LL ret = 0; for (int i = 1; i <= M; i ++) { int x = edge[i].u, y = edge[i].v, w = edge[i].w; int fx = find (x), fy = find (y); if (fx == fy) continue; fa[fx] = fy; ret += w; Insert (x, y, w), Insert (y, x, w); } return ret; } int white[MAXM]= {0}, black[MAXM]= {0}; int wn = 0, bn = 0; LL cencus(){ LL ret = 0; for (int q = 1; q <= bn; q ++) { int i = black[q]; for (int j = 1; j <= N; j ++) { fa[j] = j; Head[j] = 0; } sze = 0; int u = edge[i].u, v = edge[i].v, w = edge[i].w; fa[u] = v; Insert (u, v, w), Insert (v, u, w); Kruskal (); LL add = 0; for (int j = 0; j <= bn - 1 - (! wn); j ++) add = (add + C (bn - 1, j) * inv[j + 1] % MOD) % MOD; ret = (ret + add) % MOD; } if (wn) ret = 2ll * ret % MOD; return ret; } LL solve(){ LL ans = 0; int ext = 0; for (int i = 1; i <= M; i ++) { if (1ll * edge[i].w > X) { ext ++; continue; } for (int j = 1; j <= N; j ++) { fa[j] = j; Head[j] = 0; } sze = 0; int u = edge[i].u, v = edge[i].v, w = edge[i].w; fa[u] = v; LL x = w + Kruskal (); if (x < X) white[++ wn] = i; elseif (x == X) black[++ bn] = i; else ext ++; } ans = cencus (); ans = ans * pow2[ext] % MOD; return 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(){ N = getnum (), M = getnum (); cin >> X; if (N == 1) { puts ("0"); return0; } pow2[0] = 1; for (int i = 1; i <= max (N, M); i ++) pow2[i] = pow2[i - 1] * 2ll % MOD; fact[0] = invfact[0] = 1; inv[1] = fact[1] = invfact[1] = 1; for (int i = 2; i <= M; i ++) { inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD; fact[i] = fact[i - 1] * i % MOD; invfact[i] = invfact[i - 1] * inv[i] % MOD; } for (int i = 1; i <= M; i ++) { int u = getnum (), v = getnum (), w = getnum (); edge[i] = Edge (u, v, w); } sort (edge + 1, edge + M + 1); cout << solve () << endl; return0; }
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; int type[MAXN]= {0};
int subsize[MAXN]= {0}; bool visit[MAXN]= {false}; int rt, minval = INF, fa; voidgrvy(int n, int root, int father){ subsize[root] = 1; int maxpart = 0; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father || visit[v]) continue; grvy (n, v, root); subsize[root] += subsize[v]; maxpart = max (maxpart, subsize[v]); } maxpart = max (maxpart, n - subsize[root]); if (maxpart < minval) { rt = root; fa = father; minval = maxpart; } } structnode { int l, r, id, bel; // min value, max value, original index, 子树从属 node (int l = 0, int r = 0, int id = 0, int bel = 0) : l (l), r (r), id (id), bel (bel) {} booloperator < (const node& p) const { if (l == p.l) return r < p.r; return l < p.l; } } ; vector<node> a[MAXN]; int minv[MAXN], maxv[MAXN]; voidDFS(int root, int father, int bel){ a[rt].push_back(node (minv[root], maxv[root], root, bel)); for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to, w = Link[i].w; if (v == father || visit[v]) continue; minv[v] = min (minv[root], w); maxv[v] = max (maxv[root], w); DFS (v, root, bel); } } int MS[MAXN]= {0}; voidwork(){ minv[rt] = INF, maxv[rt] = 0; a[rt].push_back(node (minv[rt], maxv[rt], rt, rt)); for (int i = Head[rt]; i; i = Link[i].next) { int v = Link[i].to, w = Link[i].w; if (visit[v]) continue; minv[v] = min (minv[rt], w); maxv[v] = max (maxv[rt], w); DFS (v, rt, v); } sort (a[rt].begin(), a[rt].end()); pair<int, int> fir (- INF, 0), sec (- INF, 0); for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (type[x.id]) { int ms = x.r - x.l; if (ms >= fir.first) { if (x.bel != fir.second) sec = fir; fir = make_pair (ms, x.bel); } elseif (ms > sec.first && x.bel != fir.second) sec = make_pair (ms, x.bel); } } for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (! type[x.id]) { pair<int, int> now = x.bel == fir.second ? sec : fir; if (now.second) { MS[x.id] = max (MS[x.id], x.r - x.l); MS[x.id] = max (MS[x.id], now.first); } } } fir = make_pair (- INF, 0), sec = make_pair (- INF, 0); for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (type[x.id]) { if (x.r >= fir.first) { if (x.bel != fir.second) sec = fir; fir = make_pair (x.r, x.bel); } elseif (x.r > sec.first && x.bel != fir.second) sec = make_pair (x.r, x.bel); } } for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (! type[x.id]) { pair<int, int> now = x.bel == fir.second? sec : fir; int r = max (x.r, now.first); if (now.second) MS[x.id] = max (MS[x.id], r - x.l); } } fir = make_pair (INF, 0), sec = make_pair (INF, 0); for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (type[x.id]) { if (x.l <= fir.first) { if (x.bel != fir.second) sec = fir; fir = make_pair (x.l, x.bel); } elseif (x.l < sec.first && x.bel != fir.second) sec = make_pair (x.l, x.bel); } } for (int i = 0; i < (int) a[rt].size(); i ++) { node x = a[rt][i]; if (! type[x.id]) { pair<int, int> now = x.bel == fir.second? sec : fir; int l = min (x.l, now.first); if (now.second) MS[x.id] = max (MS[x.id], x.r - l); } } } voiddivide(int n, int x){ minval = INF; grvy (n, x, 0); visit[rt] = true; work (); grvy (n, rt, 0); for (int i = Head[rt]; i; i = Link[i].next) { int v = Link[i].to; if (visit[v]) continue; divide (subsize[v], v); } } bool fail[MAXN]= {false}; voiddoit(int u, int mid){ pair<int, int> fir (- INF, 0), sec (- INF, 0); for (int i = 0; i < (int) a[u].size(); i ++) { node x = a[u][i]; if (! type[x.id]) { pair<int, int> now = x.bel == fir.second ? sec : fir; if (now.second && x.r < now.first) fail[x.id] = true; if (MS[x.id] >= mid || x.r - x.l >= mid) continue; if (x.l + mid >= fir.first) { if (x.bel != fir.second) sec = fir; fir = make_pair (x.l + mid, x.bel); } elseif (x.l + mid > sec.first && x.bel != fir.second) sec = make_pair (x.l + mid, x.bel); } } fir = make_pair (INF, 0), sec = make_pair (INF, 0); for (int i = a[u].size() - 1; i >= 0; i --) { node x = a[u][i]; if (! type[x.id]) { pair<int, int> now = x.bel == fir.second ? sec : fir; if (now.second && x.l > max (x.r, now.first) - mid) fail[x.id] = true; if (MS[x.id] >= mid) continue; if (x.r <= fir.first) { if (x.bel != fir.second) sec = fir; fir = make_pair (x.r, x.bel); } elseif(x.r < sec.first && x.bel != fir.second) sec = make_pair (x.r, x.bel); } } } boolcheck(int mid){ for (int i = 1; i <= N; i ++) fail[i] = type[i]; for (int i = 1; i <= N; i ++) doit (i, mid); for (int i = 1; i <= N; i ++) if (! fail[i]) returntrue; returnfalse; }
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(){ N = getnum (); for (int i = 1; i <= N; i ++) type[i] = getnum (); int sum = 0; for (int i = 1; i <= N; i ++) sum += type[i]; if (sum >= N - 1) { if (sum == N) { puts ("0"); return0; } for (int i = 1; i <= N; i ++) if (! type[i]) { printf ("%d 0\n", i); return0; } } int maxi = 0, mini = INF; for (int i = 1; i < N; i ++) { int u = getnum (), v = getnum (), w = getnum (); Insert (u, v, w), Insert (v, u, w); maxi = max (maxi, w); mini = min (mini, w); } divide (N, 1); int left = 0, right = maxi - mini, ans; while (left <= right) { int mid = (left + right) >> 1; if (check (mid)) { ans = mid; left = mid + 1; } else right = mid - 1; } check (ans); for (int i = 1; i <= N; i ++) if (! fail[i]) { printf ("%d %d\n", i, ans); break; }