for (int x = 0; x < n; x++) { if (dfn[x] == -1) dfs(x); }
for (int i = 0; i < e.size(); i++) { auto [x, y] = e[i]; if (x == y) continue; cnt[x].insert(bel[i]); cnt[y].insert(bel[i]); } for (int x = 0; x < n; x++) { if (cnt[x].empty()) { cnt[x].insert(++tot); } }
node.resize(tot); edge.resize(tot); for (int i = 0; i < e.size(); i++) { auto [x, y] = e[i]; if (x == y) continue; edge[bel[i]].push_back(i); node[bel[i]].insert(x); node[bel[i]].insert(y); }
for (int x = 0; x < n; x++) { if (cnt[x].size() >= 2) { cut.insert(x); } } } };
voidsolve(){ int n, m; cin >> n >> m;
VBCC G(n); while (m--) { int x, y; cin >> x >> y; x--; y--; G.add_edge(x, y); } G.work();
set<int> st; for (int i = 0; i < G.tot; i++) { map<int, vector<int>> adj; for (auto id : G.edge[i]) { auto [x, y] = G.e[id]; adj[x].push_back(y); adj[y].push_back(x); } if (G.edge[i].size() <= 1) { continue; } map<int, vector<int>> degcnt; for (auto [x, vec] : adj) { degcnt[vec.size()].push_back(x); } if (degcnt.size() == 1) { if (degcnt.begin()->first == 2) { st.insert(G.edge[i].size()); } else { cout << "No\n"; return; } } else { degcnt.erase(2); if (degcnt.size() == 1) { auto [deg, vec] = *degcnt.begin(); assert(vec.size() > 1); if (vec.size() > 2) { cout << "No\n"; return; } int s = vec[0], t = vec[1]; set<int> tmp; auto dfs = [&](thisauto&& self, int x, int p, int cnt) -> void { if (x == t) { tmp.insert(cnt); return; } for (auto y : adj[x]) { if (y == p) { continue; } self(y, x, cnt + 1); } }; dfs(s, -1, 0); if (tmp.size() >= 2) { cout << "No\n"; return; } st.insert(2 * *tmp.begin()); } else { cout << "No\n"; return; } } } if (st.size() >= 2) { cout << "No\n"; } else { cout << "Yes\n"; } }
vector<Z> g(N + 1); for (int n = 1; n <= N; n++) { g[n] = Fac(n); for (int m = 1; m < n; m++) { g[n] -= g[m] * Fac(n - m); } }
vector<Z> f(N + 1); for (int n = 1; n <= N; n++) { f[n] = Fac(n); for (int m = 1; m < n; m++) { f[n] += g[m] * Fac(n - m) * (f[m] + f[n - m] - (n - m != 1)); } f[n] /= Fac(n) - g[n]; } Z res = 0; int max = 0; int lst = -1; for (int i = 0; i < N; i++) { int x; cin >> x; x--; max = std::max(max, x); if (max == i) { res += f[i - lst]; lst = i; } } cout << res << '\n';
Poly g(N + 1); [&](thisauto self, int l, int r) -> void { if (r - l <= 1) { if (l == 0) { g[l] = 0; } else { g[l] = Fac(l) - g[l]; } return; } int m = l + (r - l) / 2; self(l, m); Poly A(m - l); Poly B(r - l); for (int i = l; i < m; i++) { A[i - l] = g[i]; } for (int i = 0; i < r - l; i++) { B[i] = fac[i]; } A = A * B; for (int i = m; i < r; i++) { g[i] += A[i - l]; } self(m, r); } (0, N + 1);
Poly C = g * fac; for (int n = 1; n <= N; n++) { C[n] -= g[n] * fac[0]; C[n] -= g[n - 1] * fac[1]; C[n] = Fac(n) - C[n]; }
Poly f(N + 1); [&](thisauto self, int l, int r) -> void { if (r - l <= 1) { if (l == 0) { f[l] = 0; } else { f[l] = (f[l] + C[l]) / (Fac(l) - g[l]); } return; } int m = l + (r - l) / 2; self(l, m); Poly A(m - l); Poly B(r - l); for (int i = l; i < m; i++) { A[i - l] = f[i] * g[i]; } for (int i = 0; i < r - l; i++) { B[i] = fac[i]; } A = A * B; for (int i = m; i < r; i++) { f[i] += A[i - l]; } A.resize(m - l); B.resize(r - l); for (int i = l; i < m; i++) { A[i - l] = f[i] * fac[i]; } for (int i = 0; i < r - l; i++) { B[i] = g[i]; } A = A * B; for (int i = m; i < r; i++) { f[i] += A[i - l]; } self(m, r); } (0, N + 1); Z res = 0; int max = 0; int lst = -1; for (int i = 0; i < N; i++) { int x; cin >> x; x--; max = std::max(max, x); if (max == i) { res += f[i - lst]; lst = i; } } cout << res << '\n';
constexprint P = 998244353; voidsolve(){ int n, k; cin >> n >> k;
vector<int> a(n); for (auto& x : a) cin >> x; ranges::sort(a, greater());
int res = a[0] % P; // 特别注意 % P for (int i = 1; i + k - 2 < n; i += k - 1) { int l = i, r = i + k - 2; bool zero = false; for (int j = l; j <= r; j++) { if (a[j] == 0) { zero = true; } } if (zero) { break; } for (int j = l; j <= r; j++) { res = 1LL * res * a[j] % P; } } cout << res << endl; return; }
[&](thisauto&& self, int x) -> void { dfn[x] = ord.size(); ord.push_back(x); for (constauto& y : adj[x]) { top[y] = y == adj[x][0] ? top[x] : y; self(y); } dfm[x] = ord.size(); } (0);
auto kth_ancester = [&](int x, int k) { if (dep[x] < k) return-1; int d = dep[x] - k; while (dep[top[x]] > d) { x = parent[top[x]]; } return ord[dfn[x] - dep[x] + d]; }; // 树链剖分 end
Fenwick<int> fen1(N); // 每个点的子树权值和 Fenwick<int> fen2(N); // 每个深度的激活点数量 vector<int> active(N); auto get = [&](int x) { // 返回 x 最近的激活祖先的深度 int lo = 0, hi = dep[x] + 1; while (lo < hi) { int mid = lo + (hi - lo) / 2; int y = kth_ancester(x, mid); if (fen1(dfn[y], dfm[y]) == 0) { lo = mid + 1; } else { hi = mid; } } return dep[x] - lo + 1; }; for (int i = 0; i < Q; i++) { char op; cin >> op; if (op == '^') { int x; cin >> x; if (active[x]) { fen1.add(dfn[x], -1); fen2.add(get(x), -1); fen2.add(dep[x] + 1, 1); } else { fen2.add(get(x), 1); fen2.add(dep[x] + 1, -1); fen1.add(dfn[x], 1); } active[x] ^= true; } else { int k; cin >> k; cout << fen2(k + 2) << endl; } }