CodeForces 1418B Negative Prefixes

Negative Prefixes 因为要使得满足前缀和 $p_j < 0$ 的 $j$ 的最大值最小,所以把可以移动的元素按照从大到小排序,把大的数字尽量放在后面,这样负数在前面,就可以满足条件。 // Date: Tue Dec 5 22:46:45 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 = 110; int t, n, a[N], l[N], b[N]; int main(void) { #ifdef _DEBUG freopen("1418b.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]; } VI d; For1(i, 1, n) { cin >> l[i]; if (!l[i]) { d.pb(a[i]); } } sort(all(d), greater<int>()); int idx = SZ(d) - 1; Rof1(i, 1, n) { if (l[i]) { b[i] = a[i]; } else { b[i] = d[idx--]; } } For1(i, 1, n) { cout << b[i] << ' '; } cout << '\n'; } return 0; }

December 6, 2023 · 2 min · 380 words

CodeForces 1422B Nice Matrix

Nice Matrix tutorial 因为每行每列都需要是回文,所以四个角的数字必须相同。先考虑这四个数字,让它们都转变成某个数字,使得操作数最小,让它们都变成中位数是最优的。对于矩阵中所有的这样的四个数字都做这样的操作。实现的过程中需要考虑奇偶性。 // Date: Sun Dec 3 18:52:56 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 = 110; int t, n, m; ll a[N][N]; bool vis[N][N]; int main(void) { #ifdef _DEBUG freopen("1422b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> m; memset(vis, false, sizeof vis); For1(i, 1, n) { For1(j, 1, m) { cin >> a[i][j]; } } ll res = 0; For1(i, 1, n) { int i1 = n + 1 - i; if (i1 < i) break; For1(j, 1, m) { VI tmp; tmp.clear(); int j1 = m + 1 - j; if (j1 < j) break; if (j1 != j) { tmp.pb(a[i][j]); tmp.pb(a[i][j1]); if (i != i1) { tmp.pb(a[i1][j]); tmp.pb(a[i1][j1]); } } else { if (i != i1) { tmp.pb(a[i][j]); tmp.pb(a[i1][j]); } } int len = SZ(tmp); if (len) sort(all(tmp)); if (len == 4) { For(k, 0, len) { res += abs(tmp[k] - tmp[1]); } } else if (len == 2) { res += abs(tmp[0] - tmp[1]); } } } cout << res << '\n'; } return 0; }

December 3, 2023 · 3 min · 443 words

CodeForces 1476B Inflation

Inflation tutorial 这题有点意思,首先要发现递增 $p_0$ 总是最优的:设 $c_j = \frac{p_j}{preSum_{j-1}}$,如果递增的是 $p_i$,如果 $i > j$,此时 $c_j$ 不变;如果 $i = j$,此时 $c_j$ 变大;如果 $i < j$,那么 $c_j$ 变小。我们希望对某个元素 $p_j$ 递增的时候,之前的性质能够保持不变,所以每次都递增 $p_0$ 即可。判定整个数列满足题目要求的性质是线性的,所以可以二分答案。 // Date: Sun Dec 3 17:54:52 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 = 110; int t; ll n, k, p[N], b[N]; bool check(ll x) { For1(i, 2, n) { ll l = 100 * p[i], r = k * (x + b[i - 1]); if (l > r) return false; } return true; } int main(void) { #ifdef _DEBUG freopen("1476b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> k; memset(b, 0, sizeof b); For1(i, 1, n) { cin >> p[i]; b[i] = b[i - 1] + p[i]; } ll l = 0, r = 1e11 + 10, mid; while (l < r) { mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid + 1; } cout << r << '\n'; } return 0; }

December 3, 2023 · 3 min · 430 words

CodeForces 1561C Deep Down Below

Deep Down Below tutorial 先考虑每一个洞穴,为了要打败所有的怪物,考虑每个怪兽要求的起始等级,然后求最大值。接下来考虑所有的洞穴,每个洞穴的起始等级要求不一样,可以先从小到大排序,因为对于给定等级,判定能否通关只需要一次线性扫描,所以可以二分答案。除了二分解法,其实也可以按照单个洞穴的思路来考虑所有的洞穴。 // Date: Sun Dec 3 10:23:28 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; pair<ll, ll> b[N]; VI a[N]; bool check(ll x) { For(i, 0, n) { if (x < b[i].f1) return false; x += b[i].f2; } return true; } int main(void) { #ifdef _DEBUG freopen("1561c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; For(i, 0, n) { int len; cin >> len; a[i].clear(); For(j, 0, len) { int x; cin >> x; a[i].pb(x); } ll ma = a[i][0]; For(j, 1, len) { ma = max(ma, ll(a[i][j] - j)); } b[i].f1 = ma; b[i].f2 = len; } sort(b, b + n); ll l = 1, r = 1e18, mid; while (l < r) { mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid + 1; } cout << r + 1 << '\n'; } return 0; }

December 3, 2023 · 2 min · 422 words

CodeForces 1734C Removing Smallest Multiples

Removing Smallest Multiples tutorial 设移除 $v$ 的代价是 $f(v) = x$,那么满足 $x | v$,并且 $x, 2x, 3x, \ldots, (k - 1)x$ 在集合中都不存在,并且都已经被移除,其中 $v = kx$。可以根据这一点来求出所有的 $f(v)$,不过要反过来求。对于每个 $x$,考虑所有的 $kx$,如果 $x, 2x, 3x, \ldots, kx$ 都不在集合中,并且 $kx$ 还没有被移除,那么 $kx$ 的代价就是 $x$。 // Date: Sun Sep 17 19:57: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 LN ListNode #define LNP ListNode * #define TN TreeNode #define TNP TreeNode * #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 #ifdef _DEBUG struct ListNode { int val; ListNode *next; ListNode() : val(0), next(nullptr) {} ListNode(int val) : val(val), next(nullptr) {} ListNode(int val, ListNode *next) : val(val), next(next) {} }; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; #endif const int N = 1000010; bool vis[N]; int a[N], n, t, c[N]; int main(void) { #ifdef _DEBUG freopen("1734c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { string s; cin >> n >> s; For1(i, 1, n) { a[i] = (s[i - 1] == '1'); vis[i] = false; c[i] = 0; } ll ans = 0; For1(i, 1, n) { if (!a[i]) { if (!vis[i]) { vis[i] = true; c[i] = i; } for (int j = i + i; j <= n; j += i) { if (a[j]) break; if (!vis[j]) { vis[j] = true; c[j] = i; } } } } For1(i, 1, n) { if (!a[i]) { ans += c[i]; } } cout << ans << '\n'; } return 0; }

December 3, 2023 · 3 min · 515 words

CodeForces 1585C Minimize Distance

Minimize Distance 正数和负数分开做,从大到小排序之后,每 $k$ 个一组考虑,因为距离远的是一定要送到的,距离近的可以顺便送到。最终如果正数的最大值更大,那么最后就停留在正数。 // Date: Sat Dec 2 18:01: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 const int N = 200010; int t, n, k, a[N]; VI b, c; int solve(VI &b, ll &res) { int len = SZ(b), cnt = 0, maxb = 0; if (!len) return 0; maxb = b[0]; int cur = b[0]; cnt = 1; bool flag = true; if (cnt == k) { res += cur; flag = false; cnt = 0; } For(i, 1, len) { if (cnt == 0) { cur = b[i]; } cnt++; if (cnt == k) { if (flag) { res += cur; flag = false; } else { res += cur * 2; } cnt = 0; } } if (cnt > 0 && cnt < k) { if (flag) { res += cur; } else { res += cur * 2; } } return maxb; } int main(void) { #ifdef _DEBUG freopen("1585c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> k; b.clear(); c.clear(); For1(i, 1, n) { cin >> a[i]; if (a[i] > 0) b.pb(a[i]); else if (a[i] < 0) c.pb(abs(a[i])); } sort(all(b), greater<int>()); sort(all(c), greater<int>()); ll res = 0; int lenb = SZ(b), maxb = 0; if (lenb) { maxb = solve(b, res); } int maxc = 0; int lenc = SZ(c); if (lenc) { maxc = solve(c, res); } if (lenb && lenc) { res += min(maxb, maxc); } cout << res << '\n'; } return 0; }

December 2, 2023 · 3 min · 511 words

CodeForces 1627B Not Sitting

Not Sitting 因为要距离已经选定的点尽量远,所以只可能是四个角落的其中一个,枚举就可以了。男生为了距离女生更近一点,所以他应该尽量选择靠近中心的位置,因为靠近中心的位置可以让它距离所有点的距离都尽可能小,因此女生应该先从中心的点开始涂色,女生选择的点越少,最终两人的距离越小,两人都是最优策略,因此答案数组需要从小到大排序。 // Date: Sat Dec 2 17:04:06 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, n, m; int main(void) { #ifdef _DEBUG freopen("1627b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> m; vector<PII> corners{ {1, 1}, {1, m}, {n, 1}, {n, m}, }; VI res; For1(i, 1, n) { For1(j, 1, m) { int dis = 0; for (auto &[x, y] : corners) { int tmp = abs(x - i) + abs(y - j); dis = max(dis, tmp); } res.pb(dis); } } sort(all(res)); for (auto x : res) { cout << x << ' '; } cout << '\n'; } return 0; }

December 2, 2023 · 2 min · 373 words

CodeForces 1693A Directional Increase

Directional Increase tutorial 感觉这题有点不好想到。上面的官方题解已经很清楚了。统计每个点的增加次数和减少次数,然后观察它们的关系,得到递推公式,这个思路挺有意思的。 // Date: Wed Nov 29 18:47:27 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; ll a[N], b[N]; int main(void) { #ifdef _DEBUG freopen("1693a.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]; } bool mark = true, zero = false; ll sum = 0; b[1] = a[1]; sum = b[1]; if (b[1] < 0) { mark = false; } else if (b[1] == 0) { zero = true; } For1(i, 2, n) { sum += a[i]; b[i] = a[i] + b[i - 1]; if (b[i] < 0) { mark = false; break; } else if (b[i] > 0 && zero) { mark = false; break; } else if (b[i] == 0) { zero = true; } } if (sum && mark) mark = false; cout << (mark ? "YES\n" : "NO\n"); } return 0; }

November 30, 2023 · 2 min · 418 words

CodeForces 1649B Game of Ball Passing

Game of Ball Passing tutorial 这是一道非常经典的贪心题目,遇到过很多次。题解在上面的 tutorial 链接讨论区,比较关键的是证明。首先找到整个数列的最大值 $x$,设整个数列的和是 $sum$,如果 $x \ge sum - x$,那么可以让其他所有元素依次消耗 $x$。如果 $x < sum - x$,那么可以这样思考:设 $y = sum - x$,把 $y$ 中的元素按顺序排列,因为每个人把球传出,对应的 $a_i$ 便会递减 $1$,所以我们可以依次对 $y$ 中的每个人递减 $1$,可以一直这样下去,甚至直到剩下一个或零个人,并且整个过程是连续的,设剩下的元素和为 $z$,那么 $z < y$,并且容易证明 $z < x$(假设 $p - q = z$,如果 $p - q \ge x$,那么有 $p \ge q + x$,这和 $x$ 是最大值矛盾),所以有 $z < x < y$,由于 $y$ 到 $z$ 的过程是连续的,所以一定存在某个时刻恰好等于 $x$,此时就转化成了第一种情况。 // Date: Wed Nov 29 21:36:17 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; ll a[N], sum; int main(void) { #ifdef _DEBUG freopen("1649b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n; sum = 0; ll ma = -1; For1(i, 1, n) { cin >> a[i]; sum += a[i]; ma = max(ma, a[i]); } if (!sum) cout << "0\n"; else if (2 * ma <= sum) cout << 1 << '\n'; else { cout << 2 * ma - sum << '\n'; } } return 0; }

November 30, 2023 · 3 min · 427 words

CodeForces 1364B Most socially-distanced subsequence

Most socially-distanced subsequence 这道题目比较简单,对于一个递增或者递减的连续子数列,中间的数字对于答案是没有贡献的,只有两端的端点有意义,因此这道题就转化为求整个数列所有的极大值和极小值。 // Date: Wed Nov 29 22:01: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 = 100010; int t, n, a[N], b[N]; int main(void) { #ifdef _DEBUG freopen("1364b.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 idx = 1; bool flag = true; b[idx++] = a[1]; if (a[2] > a[1]) flag = true; else flag = false; For1(i, 3, n) { if (flag) { if (a[i] > a[i - 1]) ; else { b[idx++] = a[i - 1]; flag = false; } } else { if (a[i] < a[i - 1]) ; else { b[idx++] = a[i - 1]; flag = true; } } } b[idx++] = a[n]; cout << idx - 1 << '\n'; For(i, 1, idx) { cout << b[i] << ' '; } cout << '\n'; } return 0; }

November 30, 2023 · 2 min · 413 words

CodeForces 1804B Vaccination

Vaccination 这是一道很不错的贪心题目。为了使得开箱的疫苗最少,我们尽量让每个人接种时间靠后,来延长疫苗的过期时间,使得疫苗能够被后面的人接种到。因此对于第一个人 $a_1$,我们就可以规定开箱时间是 $a_1 + w$,那么这箱的过期时间是 $a_1 + w + d$,在这箱过期之前最多能接种 $k$ 个人,如果这之前多于 $k$ 个人,那么只能再开一箱了。这样下去,就能够保证每个人都能接种,并且每箱都能最大化利用,也就是尽量少地开箱。 // Date: Thu Nov 30 21:15:29 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, k, d, w, a[N]; int main(void) { #ifdef _DEBUG freopen("1804b.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> k >> d >> w; For1(i, 1, n) { cin >> a[i]; } int res = 0, cnt = 0; For1(i, 1, n) { if (!cnt) { int top = a[i] + w + d; cnt = 1; res++; ++i; while (cnt < k && i <= n) { if (a[i] <= top) { cnt++; ++i; } else break; } --i; cnt = 0; } } cout << res << '\n'; } return 0; }

November 30, 2023 · 2 min · 396 words

CodeForces 1717C Madoka and Formal Statement

Madoka and Formal Statement 分三种情况,当 $a_i \ge b_i$ 的时候比较简单。当 $a_i \lt b_i$ 的时候,需要递增 $a_i$,此时它的上限是 $b_{i + 1} + 1$,如果达不到这个上限那么就没有解。 // Date: Sun Nov 26 20:01:43 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("1717c.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]; } bool flag = true; For1(i, 1, n) { if (a[i] > b[i]) { flag = false; break; } else if (a[i] < b[i]) { int idx = i + 1; if (idx == n + 1) idx = 1; if (b[idx] + 1 < b[i]) { flag = false; break; } } } cout << (flag ? "YES\n" : "NO\n"); } return 0; }

November 26, 2023 · 2 min · 402 words

CodeForces 1810C Make It Permutation

Make It Permutation 两种操作都和顺序无关,要生成一个 $[1, n]$ 的排列,先把原数组排序,对于每个点有三种策略:1. 从这个点开始后面的元素都删除。2. 当前元素比需要的下标 $idx$ 小,此时删除这个元素。3. 当前元素比需要的下标 $idx$ 大,补足中间缺少的数字。注意整型溢出。 // Date: Sun Nov 26 16:48:05 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, c, d, a[N]; int main(void) { #ifdef _DEBUG freopen("1810c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> c >> d; For1(i, 1, n) { cin >> a[i]; } sort(a + 1, a + 1 + n); ll res = ll(n) * c + d, cur = 0; int idx = 1; For1(i, 1, n) { if (a[i] == idx) { idx++; } else { ll cur1 = cur + ll(n - i + 1) * c; if (i > 1) { res = min(res, cur1); } else { res = min(res, cur1 + d); } if (a[i] > idx) { cur += ll(a[i] - idx) * d; idx = a[i] + 1; } else { cur += c; } } } res = min(res, cur); cout << res << '\n'; } return 0; }

November 26, 2023 · 3 min · 436 words

CodeForces 1733C Parity Shuffle Sorting

Parity Shuffle Sorting tutorial 题目要求单调不减,同时也不要求操作次数最少。一次操作可以改变一个数字,最少操作 $n$ 次可以对所有的数字都修改一次。如果所有数字相等也可以满足条件,所以利用这一点,先把 $a_1$ 和 $a_n$ 操作成相等的元素,然后对中间的每个数字 $a_i$,根据 $a_i + a_1$ 的奇偶性来让 $a_i$ 和 $a_1$ 或者 $a_n$ 配对,这样最后所有的元素都相等。 // Date: Sat Nov 25 20:41: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 = 100010; int t, n, a[N]; int main(void) { #ifdef _DEBUG freopen("1733c.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]; } if (n == 1) { cout << "0\n"; continue; } vector<PII> res; res.pb({1, n}); if ((a[1] + a[n]) & 1) a[n] = a[1]; else a[1] = a[n]; For1(i, 2, n - 1) { int tmp = a[1] + a[i]; if (tmp & 1) res.pb({1, i}); else res.pb({i, n}); } int m = SZ(res); cout << m << '\n'; if (m) { For(i, 0, m) { cout << res[i].f1 << ' ' << res[i].f2 << '\n'; } } } return 0; }

November 25, 2023 · 2 min · 413 words

CodeForces 1538C Number of Pairs

Number of Pairs 题目和元素顺序无关,先排序,然后对每个元素二分找符合条件的左端点和右端点,注意边界,二分之前如果左右端点是空集,直接返回 $-1$。 // Date: Sat Nov 25 19:10:08 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, l, r, a[N]; int find_left(int left, int right, int x) { if (left > right) return -1; int l = left, r = right, mid; while (l < r) { mid = (l + r) / 2; if (a[mid] >= x) r = mid; else l = mid + 1; } if (a[r] >= x) return r; return -1; } int find_right(int left, int right, int x) { if (left > right) return -1; int l = left, r = right, mid; while (l < r) { mid = (l + r + 1) / 2; if (a[mid] <= x) l = mid; else r = mid - 1; } if (a[l] <= x) return l; return -1; } int main(void) { #ifdef _DEBUG freopen("1538c.in", "r", stdin); #endif std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> t; while (t--) { cin >> n >> l >> r; For1(i, 1, n) { cin >> a[i]; } sort(a + 1, a + 1 + n); ll res = 0; For1(i, 1, n) { int left = find_left(i + 1, n, l - a[i]), right = find_right(i + 1, n, r - a[i]); if (left != -1 && right != -1) { res += right - left + 1; } } cout << res << '\n'; } return 0; }

November 25, 2023 · 3 min · 499 words