CodeForces 1768C Elemental Decompress

Elemental Decompress 先把原数组从大到小排序,然后依次往两个答案数组 $p_1$ 和 $p_2$ 中填数,两个数组是等价的,不妨优先在 $p_1$ 中填,如果一个数字在两个数组中都已经用过了,说明这个数字出现了三次,可以判定无解。填完一遍之后,再从大到小往两个 $p$ 数组中从前往后填入各自缺少的数字,如果填入的数字大于原数组,那么也无解。 // Date: Sun Dec 10 15:00:10 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 200010; struct point { int v, p1, p2, idx; }; int t, n; point a[N]; bool vis[2][N]; int main(void) { #ifdef _DEBUG freopen("1768c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; For1(i, 1, n) { cin >> a[i].v; a[i].idx = i; a[i].p1 = a[i].p2 = 0; } sort(a + 1, a + n + 1, [&](const point &x, const point &y) { if (x.v > y.v) return true; else if (x.v == y.v) return x.idx < y.idx; return false; }); memset(vis, false, sizeof vis); bool flag = true; For1(i, 1, n) { int x = a[i].v; if (!vis[0][x]) { vis[0][x] = true; a[i].p1 = x; } else if (!vis[1][x]) { vis[1][x] = true; a[i].p2 = x; } else { flag = false; break; } } VI rem1; Rof1(i, 1, n) { if (!vis[0][i]) { rem1.pb(i); } } if (nonempty(rem1)) { int idx = 0; For1(i, 1, n) { if (!a[i].p1) { if (rem1[idx] <= a[i].v) { a[i].p1 = rem1[idx++]; } else { flag = false; break; } } } } VI rem2; Rof1(i, 1, n) { if (!vis[1][i]) { rem2.pb(i); } } if (nonempty(rem2)) { int idx = 0; For1(i, 1, n) { if (!a[i].p2) { if (rem2[idx] <= a[i].v) { a[i].p2 = rem2[idx++]; } else { flag = false; break; } } } } if (flag) { cout << "YES\n"; sort(a + 1, a + n + 1, [&](const point &x, const point &y) { return x.idx < y.idx; }); For1(i, 1, n) { cout << a[i].p1 << ' '; } cout << '\n'; For1(i, 1, n) { cout << a[i].p2 << ' '; } cout << '\n'; } else { cout << "NO\n"; } } return 0; }

December 10, 2023 · 3 min · 574 words

CodeForces 1775B Gardener and the Array

Gardener and the Array tutorial tutorial on bilibili 思路参考上面 bilibili 的视频链接。 如果 $x | y = x$,那么 $y$ 这个数字是可有可无的,如果能够在数组中找到任何一个这样的 $y$,那么就存在解:子序列 $a$ 是所有的元素,子序列 $b$ 是除了 $y$ 之外的所有元素。$y$ 的特征是它所有的位在其它元素中存在至少一次,也就是 $y$ 的二进制位在所有元素中出现了至少两次。如果 $y_1$ 有一个位是独一无二的,那么一定不满足 $x | y_1 = x$,所以只需要找到一个所有二进制位在所有元素中出现至少两次的元素。 // Date: Sun Dec 10 14:25:09 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 100010; int t, n; int main(void) { #ifdef _DEBUG freopen("1775b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; vector<VI> a(n); map<int, int> m; For(i, 0, n) { int len; cin >> len; For1(j, 1, len) { int x; cin >> x; m[x]++; a[i].pb(x); } } bool flag = false; For(i, 0, n) { bool mark = true; for (auto x : a[i]) { if (m[x] < 2) { mark = false; break; } } if (mark) { flag = true; break; } } cout << (flag ? "YES\n" : "NO\n"); } return 0; }

December 10, 2023 · 2 min · 413 words

CodeForces 1498B Box Fitting

Box Fitting 对于每一行,从大到小放是收益最大的。由于每个矩形的长度都是 2 的幂,所以从大到小循环 2 的幂即可,直到把所有的矩形都放完。 // Date: Sun Dec 10 12:25:53 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 100010; int t, n, w, a[N]; int main(void) { #ifdef _DEBUG freopen("1498b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> w; map<int, int> m; For1(i, 1, n) { cin >> a[i]; m[a[i]]++; } int res = 0; while (nonempty(m)) { res++; int rem = w; int len = SZ(m); Rof1(i, 0, 31) { int x = (1 << i); if (!rem) break; if (!has(m, x) || rem < x) continue; int cnt = m[x]; int hold = rem / x; if (hold >= cnt) { m.erase(x); rem -= cnt * x; } else { m[x] -= hold; if (!m[x]) m.erase(x); rem -= hold * x; } } } cout << res << '\n'; } return 0; }

December 10, 2023 · 2 min · 408 words

CodeForces 1676F Longest Strike

Longest Strike 找到符合要求的数字,排序之后寻找最长连续的子数组。注意考虑长度是 1 的边界情况。 // Date: Sun Dec 10 11:26:31 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 200010; int a[N], t, n, k; int main(void) { #ifdef _DEBUG freopen("1676f.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> k; map<int, int> m; For1(i, 1, n) { cin >> a[i]; m[a[i]]++; } VI b; for (auto &[x, y] : m) { if (y >= k) b.pb(x); } sort(all(b)); int len = SZ(b); if (!len) { cout << "-1\n"; continue; } int res = 1, cur = 0, l = 0, r = -1; int resl = b[0], resr = b[0]; For(i, 1, len) { if (b[i] == b[i - 1] + 1) { r = i; cur = r - l + 1; if (cur > res) { res = cur; resl = b[l]; resr = b[r]; } } else { l = i; } } if (res != 0) { cout << resl << ' ' << resr << '\n'; } else { cout << "-1\n"; } } return 0; }

December 10, 2023 · 3 min · 442 words

CodeForces 1859B Olya and Game with Arrays

Olya and Game with Arrays tutorial 一道有趣的题目。因为只能从每个数组中拿出一个数字,所以每个数组有用的数字只有从小到大排序之后的前两个数字。另外一个性质是:如果往一个数组里面加入数字,那么这个数组的贡献不会变大。当从一个数组中取出一个数字之后,这个数字并不会消失,它会出现在其它数组中,也就是说所有数组的最小值最终一定会贡献给最终答案。综合这几点,就可以发现,我们可以把从每个数组中取出的数字放到同一个数组 $A$ 中,这个数组的最终贡献就是所有数组的最小值。剩下的数组的贡献是原先每个数组的第二小的值。由于数组 $A$ 的贡献是固定的,要让最终的结果最大,只需要让 $A$ 等于所有数组中第二小的值最小。 // Date: Sat Dec 9 21:17:37 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 50010; int t, n; PII a[N]; int main(void) { #ifdef _DEBUG freopen("1859b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; int cnt, mb = 1e9 + 10; For1(i, 1, n) { cin >> cnt; VI tmp(cnt, 0); For(j, 0, cnt) { cin >> tmp[j]; } sort(all(tmp)); a[i].f1 = tmp[0]; a[i].f2 = tmp[1]; mb = min(mb, a[i].f1); } sort(a + 1, a + n + 1, [&](const PII &x, const PII &y) { if (x.f2 < y.f2) return true; else if (x.f2 > y.f2) return false; return x.f1 < y.f1; }); ll res = mb; For1(i, 2, n) { res += a[i].f2; } cout << res << '\n'; } return 0; }

December 9, 2023 · 2 min · 407 words

CodeForces 1847B Hamon Odyssey

Hamon Odyssey 很有意思的一道题。要求分组之后的和最小,同时,分组的个数要尽量多。首先发现如果某一组的强度是 $0$,那么所有组的强度之后最坏应该是 $0$(因为此时所有元素的按位与一定是 $0$)。又要求分组尽量多,所以就需要找到尽量多的子数组,使得这个子数组的按位与是 $0$,对于其中剩下的那些按位与不是 $0$ 的元素,把它们分到相邻的任意一个合法的组即可。如果找不到任何一个组的强度是 $0$,那么最终的解是整个数组,因为任何一个子数组的强度都是正数,分开之后强度和会更大。 // Date: Sat Dec 9 20:25:47 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 200010; int t, a[N], n; int main(void) { #ifdef _DEBUG freopen("1847b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; For1(i, 1, n) { cin >> a[i]; } int res = 0; ll cur = 0; bool flag = true; For1(i, 1, n) { if (flag) { cur = a[i]; flag = false; } else { cur = cur & a[i]; } if (cur == 0) { res++; flag = true; } } if (!res) res = 1; cout << res << '\n'; } return 0; }

December 9, 2023 · 2 min · 379 words

CodeForces 1837C Best Binary String

Best Binary String tutorial 选择任意一个区间逆序是一个操作。 从后往前扫描,后缀的 $?$ 可以全部替换成 $1$ 如果遇到 $0$,那么可能会需要一次操作(如果 $0$ 的前面都是 $0$ 或者 $?$,那么就不需要) $0$ 之后紧接的 $?$ 可以替换成 $0$,这样结果不会更差 如果遇到 $1$,那么就找到了这次操作的左端,同时 $1$ 左边紧接的 $1$ 可以算作一次操作,如果遇到 $?$ 那么可以替换成 $1$ 之后再遇到 $0$ 就是新的一轮操作 // Date: Sat Dec 9 16:41:32 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 300010; int t, d0[N], d1[N]; string s; int main(void) { #ifdef _DEBUG freopen("1837c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> s; int n = SZ(s), cnt = 0; For(i, 0, n) { if (s[i] == '?') cnt++; } if (!cnt) { cout << s << '\n'; continue; } bool flag = false; Rof(i, 0, n) { if (s[i] == '?') { if (!flag) s[i] = '1'; else { s[i] = '0'; } } else if (s[i] == '1') { if (!flag) continue; else { flag = false; } } else { if (!flag) flag = true; } } cout << s << '\n'; } return 0; }

December 9, 2023 · 2 min · 423 words

CodeForces 1836B Astrophysicists

Astrophysicists tutorial 观察可以发现可以让前面的 $n - 1$ 个人每人的分配数量是 $\frac{g - 1}{2}$,这样前面 $n-1$ 个人什么都得不到。剩下的硬币全部给一个人,判断余数即可。 // Date: Fri Dec 8 21:06:31 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif ll t, n, k, g; int main(void) { #ifdef _DEBUG freopen("1836b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> k >> g; ll res = 0, tot = k * g, sum = 0, x; if (g & 1) { x = g / 2; } else { x = g / 2 - 1; } For(i, 1, n) { sum += x; res += x; } if (sum >= tot) { cout << tot << '\n'; continue; } ll v = (tot - sum) % g; if (v <= x) { res += v; } else { res -= (g - v); } cout << res << '\n'; } return 0; }

December 8, 2023 · 2 min · 405 words

CodeForces 1834B Maximum Strength

Maximum Strength 按位考虑,从高位到低位找到第一个不相同的位置,这个位置的贡献是 $abs(a[i] - b[i])$,其它位置的贡献都是 9。 // Date: Fri Dec 8 20:34:42 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif int t; int main(void) { #ifdef _DEBUG freopen("1834b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { string a, b; cin >> a >> b; int lena = SZ(a), lenb = SZ(b), res = 0; if (lena == lenb) { int idx = -1, len = 0; For(i, 0, lena) { if (a[i] != b[i]) { idx = i; len = lena - (idx + 1); break; } } if (idx != -1) res = 9 * len + abs(a[idx] - b[idx]); } else { res = 9 * (lenb - 1) + abs(b[0] - '0'); } cout << res << '\n'; } return 0; }

December 8, 2023 · 2 min · 388 words

CodeForces 1821B Sort the Subarray

Sort the Subarray 先从两侧确定最小的左右边界,然后对 $b$ 数组,在保证有序的情况下,向两边扩展得到最大的左右边界。 // Date: Fri Dec 8 20:00:02 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 200010; int n, a[N], b[N], t; int main(void) { #ifdef _DEBUG freopen("1821b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; For1(i, 1, n) { cin >> a[i]; } For1(i, 1, n) { cin >> b[i]; } int l = 1, r = n; For1(i, 1, n) { if (a[i] != b[i]) { l = i; break; } } Rof1(i, 1, n) { if (a[i] != b[i]) { r = i; break; } } while (l > 1 && b[l - 1] <= b[l]) --l; while (r < n && b[r + 1] >= b[r]) ++r; cout << l << ' ' << r << '\n'; } return 0; }

December 8, 2023 · 2 min · 398 words

CodeForces 1811C Restore the Array

Restore the Array 这道题的细节还是挺多的。大题思路就是对于当前的 $b_i$,如果 $a_i$ 还没有确定,那么令 $a_i = b_i$,这样可以留出 $a_{i + 1}$ 的位置给 $b_{i + 1}$ 确定。如果 $a_{i}$ 已经确定,检查它是否恰好等于 $b_{i}$,如果不等,那么只能让 $a_{i + 1} = b_i$。接下来如果 $b_i < b_{i + 1}$,同时 $a_i = b_i$,此时 $a_{i+1}$ 这个位置就「没有用了」,不妨令 $a_{i + 1} = 0$,原因是 $a_{i + 1}$ 不能等于 $b_{i + 1}$(如果 $a_{i + 1} = b_{i + 1}$,那么 $b_{i} = b_{i + 1}$,然而 $b_i < b_{i + 1}$)。 // Date: Fri Dec 8 19:17:03 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 200010; int t, n, a[N], b[N]; int main(void) { #ifdef _DEBUG freopen("1811c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { int n1; cin >> n; n1 = n - 1; For1(i, 1, n1) { cin >> b[i]; } memset(a, -1, sizeof a); For1(i, 1, n1) { bool flag = false; if (a[i] == -1) { a[i] = b[i]; flag = true; } else { if (a[i] < b[i]) { a[i + 1] = b[i]; } else { flag = true; } } if (b[i] < b[i + 1]) { if (flag) { a[i + 1] = 0; if (i + 2 <= n) { a[i + 2] = b[i + 1]; } } } } if (a[n] == -1) a[n] = 0; For1(i, 1, n) { cout << a[i] << ' '; } cout << '\n'; } return 0; }

December 8, 2023 · 3 min · 485 words

CodeForces 1809B Points on Plane

Points on Plane 模拟前几个样例可以发现需要根据奇偶性讨论。反向考虑,当结果为 $0, 1, 2, 3, 4$ 的时候的节点分配是怎样的,可以得到当答案 $k$ 是奇数的时候,能够放下的最多的点数是 $2(k + 1)(\frac{k}{2} + 1)$;当答案 $k$ 是偶数的时候,能够放下的最多的点数是 $(k + 1)^2$。然后就可以二分答案了。 // Date: Thu Dec 7 21:25:48 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif int t; ll n; bool check(ll x) { ll cnt; if (x & 1) { cnt = (x + 1) * (x / 2 + 1) * 2; } else { cnt = (1 + x) * (1 + x); } return cnt < n; } int main(void) { #ifdef _DEBUG freopen("1809b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; if (n == 1) { cout << "0\n"; continue; } ll l = 0, r = 1e10, mid; while (l < r) { mid = (l + r + 1) / 2; if (check(mid)) l = mid; else r = mid - 1; } cout << l + 1 << '\n'; } return 0; }

December 7, 2023 · 2 min · 416 words

CodeForces 1802B Settlement of Guinea Pigs

Settlement of Guinea Pigs 当没有医生来之前,每增加一只猪,就需要新增一个笼子。当医生来了之后,知道了所有猪的性别,设一共有 $cnt$ 只,那么最多需要的笼子个数是:$\frac{cnt}{2} + 1$。 // Date: Thu Dec 7 19:42:36 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif const int N = 100010; int t, n, a[N]; int main(void) { #ifdef _DEBUG freopen("1802b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; For1(i, 1, n) { cin >> a[i]; } int res = 0, cur = 0, cnt = 0; For1(i, 1, n) { if (a[i] == 1) { cnt++; cur++; res = max(res, cur); } else { if (cnt) { cur = cnt / 2 + 1; } res = max(res, cur); } } cout << res << '\n'; } return 0; }

December 7, 2023 · 2 min · 373 words

CodeForces 1371C A Cookie for You

A Cookie for You 挺有趣的一道题目。 先观察第一类人,可以发现无论当前的局面是什么,第一类人总可以把饼干一直吃下去。 再观察第二类人,可以发现他们能够吃到的最多的饼干的数量是 $min(a, b)$,即使在第一类人的「帮助」下,也不能够增加第二类人能够吃到的饼干的数量。 // Date: Wed Dec 6 22:45:31 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif int t; ll a, b, n, m; int main(void) { #ifdef _DEBUG freopen("1371c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> a >> b >> n >> m; bool flag = true; ll a1 = min(a, b); if (a1 < m) { flag = false; } else { ll rem = a + b - m; if (rem < n) flag = false; } cout << (flag ? "YES\n" : "NO\n"); } return 0; }

December 6, 2023 · 2 min · 362 words

CodeForces 1372B Omkar and Last Class of Math

Omkar and Last Class of Math 对于给定的 $n$,要找到 $x$ 和 $y$,满足 $x + y = n$,并且满足 $LCM(x, y)$ 尽可能小。显然满足条件的 $LCM(x, y)$ 的一个上界是 $n - 1$。当 $n$ 是偶数的时候,只需要取 $x = y = \frac{n}{2}$。当 $n$ 是奇数的时候,设 $y = kx$,那么 $x + kx = (k + 1)x = n$,所以只需要枚举 $[1, \sqrt{n}]$ 就可以了,此时枚举变量可能是 $k + 1$,也可能是 $x$,这两种情况分别求出 $x$ 和 $y = kx$,其中 $LCM(x, y) = LCM(x, kx) = kx = y$,维护最小值即可。 // Date: Wed Dec 6 00:57:15 2023 #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> using namespace std; const int INF = 0x3f3f3f3f, MOD = 1e9 + 7; const double eps = 1e-8; const int dir[8][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}, }; typedef long long ll; typedef unsigned long long ull; typedef vector<int> VI; typedef pair<int, int> PII; const ull Pr = 131; #define For(i, a, b) for (int i = int(a); i < int(b); ++i) #define Rof(i, a, b) for (int i = int(b) - 1; i >= int(a); --i) #define For1(i, a, b) for (int i = int(a); i <= int(b); ++i) #define Rof1(i, a, b) for (int i = int(b); i >= int(a); --i) #define ForE(i, j) for (int i = h[j]; i != -1; i = ne[i]) #define f1 first #define f2 second #define pb push_back #define has(a, x) (a.find(x) != a.end()) #define nonempty(a) (!a.empty()) #define all(a) (a).begin(), (a).end() #define SZ(a) int((a).size()) #ifdef _DEBUG #define debug1(x) cout << #x " = " << x << endl; #define debug2(x, y) cout << #x " = " << x << " " #y " = " << y << endl; #define debug3(x, y, z) \ cout << #x " = " << x << " " #y " = " << y << " " #z " = " << z << endl; #else #define debug1 #define debug2 #define debug3 #endif int t; ll n; int main(void) { #ifdef _DEBUG freopen("1372b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; PII res = {1, n - 1}; if (n % 2 == 0) { res = {n / 2, n / 2}; } else { ll cur = n - 1; for (ll i = 2; i * i <= n; i++) { if (n % i == 0) { ll x = i, y = n / i; int tmp = max((x - 1) * y, y); if (tmp < cur) { res = {(x - 1) * y, y}; cur = tmp; } tmp = max((y - 1) * x, x); if (tmp < cur) { res = {(y - 1) * x, x}; cur = tmp; } } } } cout << res.f1 << ' ' << res.f2 << '\n'; } return 0; }

December 6, 2023 · 3 min · 491 words