3.6
Lonely Mountain Dungeons
算貢獻算了半天還錯了, 這種採用容斥可以減少細節處理, 程式碼註釋有
#include <bits/stdc++.h> using namespace std; #define endl "\n" #define int long long typedef long long ll; void solve() { int n, b, x; cin >> n >> b >> x; // cout << n << b << x << endl; vector<int> a(n + 1); map<int, int> mp; for (int i = 1; i <= n; i++) cin >> a[i], mp[a[i]]++; int maxn = *max_element(a.begin() + 1, a.begin() + 1 + n), ans = 0; auto calc = [&](int x, int d) { // x 代表人數, d 代表組數 // 假設全排成一排( x 個人到 x 組都是一個) int ans = x * (x - 1) / 2; // t 代表 x 人分為 d 組,每組都有的共同人數 int t = x / d; // del代表有 del 組多出來一個人 int del = x % d; // 1. 那麼對於這些人數,我們組內沒有貢獻的,我們容斥需要減去這些貢獻(C(t, 2)) ans -= d * t * (t - 1) / 2; // 2. 有 del 組多出來一個人, 對於多出來的那個人,我們會減少的貢獻是他組內的 t 個人 ans -= del * t; return ans * b; }; for (int i = 1; i <= maxn; i++) { int sum = -(i - 1) * x; // cout << "TEST " << i << endl; for (auto [id, v] : mp) { if (id <= i) { // cout << id << endl; sum += id * (id - 1) / 2 * b * v; continue; } sum += v * calc(id, i); // cout << v * calc(id, i) << ' ' << id << endl; } ans = max(ans, sum); } cout << ans << endl; } signed main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int T = 1; cin >> T; while (T--) solve(); // solve(); return 0; }
Microcycle
我們取一顆最大生成樹, 那麼一條非樹邊會產生一個環, 我們找到這樣一條權值最小的邊去 dfs
#include <bits/stdc++.h> using namespace std; #define endl "\n" #define int long long typedef long long ll; const int N = 2e5 + 100; struct node { int x, y, v; } e[N]; bool cmp(node a, node b) { return a.v > b.v; } vector<int> g[N]; int fa[N], vis[N]; int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } vector<int> cir; void dfs(int x, int t) { vis[x] = 1; cir.push_back(x); if (x == t) { cout << cir.size() << endl; for (auto i : cir) cout << i << ' '; cout << endl; return; } for (auto y : g[x]) { if (!vis[y]) dfs(y, t); } cir.pop_back(); } void solve() { int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { int x, y, v; cin >> x >> y >> v; e[i] = {x, y, v}; } cir.clear(); for (int i = 1; i <= n; i++) fa[i] = i, vis[i] = 0, g[i].clear(); sort(e + 1, e + 1 + m, cmp); int minn = INT_MAX / 2, id; for (int i = 1; i <= m; i++) { auto [x, y, v] = e[i]; int fx = find(x), fy = find(y); if (fx != fy) { fa[fx] = fy; } else { minn = min(minn, v); id = i; } } for (int i = 1; i <= m; i++) { if (i != id) { auto [x, y, v] = e[i]; g[x].push_back(y); g[y].push_back(x); } } cout << minn << ' '; dfs(e[id].x, e[id].y); } signed main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int T = 1; cin >> T; while (T--) solve(); return 0; }