A.
显然。
1 2 3 4 5 6 7 8 9 10 11 12
| void solve() { int x, y, k; cin >> x >> y >> k; if (y <= x) { cout << x << "\n"; } else { int t = min(x + k, y); cout << y + y - t << "\n"; } }
|
B.
选择两个子集,极差之和最小。
显然是排序之后分两半。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void solve() { int n; cin >> n; vi a(n * 2); rep(i, n * 2) cin >> a[i]; sort(all(a)); vi x, y; rep(i, n) { x.pb(a[i]); } rep(i, n) { y.pb(a[i + n]); } int ans = a.back() - a[n] + a[n - 1] - a[0]; cout << ans << "\n"; rep(i, n) { cout << x[i] << " " << y[i] << "\n"; } }
|
C.
枚举偶数长度 ,然后选择可能的方案。
非常好写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| int coef[10][50]; void solve() { int n; cin >> n; vc<string> s(n); rep(i, n) cin >> s[i]; ll ans = 0; for (int l = 2; l <= 10; l += 2) { memset(coef, 0, sizeof coef); rep(i, n) { if (sz(s[i]) < l) { int sum = 0; int c = 0; for (int j = sz(s[i]) - 1; j >= 0; j--) { c += 1; if (c > l / 2) { sum -= s[i][j] - '0'; } else { sum += s[i][j] - '0'; } } if (sum >= 0) coef[sz(s[i])][sum] += 1; sum = 0; c = 0; rep(j, sz(s[i])) { c += 1; if (c > l / 2) { sum -= s[i][j] - '0'; } else { sum += s[i][j] - '0'; } } if (sum >= 0) coef[sz(s[i])][sum] += 1; } } rep(i, 1, l) { rep(j, 50) { ans += 1ll * coef[i][j] * coef[l - i][j]; } } } cout << ans / 4 << "\n"; }
|
D.
简单讲讲我的做法。
考虑所有数字一定互不相同。(异或性质)
那么只需要满足 ,即 ,就可以满足这个序列是
我们假设 ,使得 为
那么 ,由于 互不相同,那么 肯定也互不相同。
那只需要 即可。
考虑对于一个数字 ,, 会产生 个区间。
综上,可以用前缀和维护,交集的话相当于出现了 次,复杂度 。
感觉别的做法都比我的简单啊。/ll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| void solve() { int n; cin >> n; vi a(n); rep(i, 1, n) { cin >> a[i]; a[i] ^= a[i - 1]; } debug(a); vi s(n * 4); int t = n - 1; rep(i, 1, n) { int x = a[i]; for (int j = 20; j >= 0; j--) { if (t >> j & 1) { int k = 1 << j; int l = x & ~(k - 1); int r = l + k; s[l] += 1; s[r] -= 1; x ^= k; } } s[x] += 1; s[x + 1] -= 1; } rep(i, 1, n) { s[i] += s[i - 1]; } rep(i, n) { if (s[i] == n - 1) { rep(j, n) { cout << (a[j] ^ i) << " \n"[j + 1 == n]; } return; } } }
|
E.
贪心建边建立所有的关系,然后跑拓扑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| void solve() { int n; cin >> n; vc<pii> a(n); rep(i, n) cin >> a[i].fi; rep(i, n) cin >> a[i].se; int m; cin >> m; vc<pii> b(m); rep(i, m) cin >> b[i].fi; rep(i, m) cin >> b[i].se; sort(all(a)); sort(all(b)); vc<pii> sa(n); vc<pii> sb(m); for (int i = n - 1; i >= 0; i--) { sa[i] = {a[i].se, i}; if (i + 1 < n && sa[i + 1] > sa[i]) { sa[i] = sa[i + 1]; } } for (int i = m - 1; i >= 0; i--) { sb[i] = {b[i].se, i}; if (i + 1 < m && sb[i + 1] > sb[i]) { sb[i] = sb[i + 1]; } } vc<vi> g(n + m); vi d(n + m); vi ans(n + m, -1); rep(i, n) { int j = lower_bound(all(b), pii(a[i].se + 1, 0)) - begin(b); if (j == m) { continue; } else { int x = n + sb[j].se; int y = i; g[x].pb(y); d[y] += 1; } } rep(i, m) { int j = lower_bound(all(a), pii(b[i].se + 1, 0)) - begin(a); if (j == n) { continue; } else { int x = sa[j].se; int y = n + i; g[x].pb(y); d[y] += 1; } } queue<int> q; rep(i, n + m) { if (!d[i]) { ans[i] = i < n; q.emplace(i); } } while (!q.empty()) { int u = q.front(); q.pop(); for (auto v : g[u]) { ans[v] = ans[u]; if (--d[v] == 0) { q.emplace(v); } } } ans.resize(n); cout << count(all(ans), 1) << " " << count(all(ans), -1) << " " << count(all(ans), 0) << "\n"; }
|
F.
假设 ,那么我们知道答案是 。
可以让 ,那么我们只需确定 就可以确定下来 ,再确定最小值 ,就可以唯一确定一个序列 。
现在 不为 ,考虑容斥。
首先假设同样假设最小值为 ,能算出来总方案数。
多算的部分就是所有的 ,并且满足整个序列为非负整数的方案数。可以建立一个矩阵 ,$[M^{n-1}]{i,j}ij\sum{i,j} [M^{n-1}]_{i,j}$。
后者可以用矩阵快速幂,感觉难的部分在想到枚举最小值,然后容斥。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void solve() { int n, x, k; cin >> n >> x >> k; int ans = 1ll * (x + k) * power(2 * k + 1, n - 1) % P; if (x == 0) { cout << ans << "\n"; return; } vector<vector<int>> base(x, vi(x)); rep(i, x) { rep(j, x) { if (abs(i - j) <= k) { base[i][j] = 1; } } } auto mat = power(base, n - 1); rep(i, x) { rep(j, x) { ans += P - mat[i][j]; if (ans >= P) { ans -= P; } } } cout << ans << "\n"; }
|
G.
wa53…