Codeforces Round 895 (Div. 3)

1|0A. Two Vessels


#include <bits/stdc++.h> using namespace std; #define int long long const int mod = 1e9 + 7; using i64 = long long; void solve() { int a, b, c; cin >> a >> b >> c; a = abs( a - b ) , c = c * 2 ; cout << ( a + c - 1 ) / c << "\n"; } int32_t main() { int t; cin >> t; while (t--) solve(); return 0; }

2|0B. The Corridor or There and Back Again


二分答案,暴力判断

#include <bits/stdc++.h> using namespace std; #define int long long constexpr int mod = 1e9 + 7, inf = 1e18; using i64 = long long; using pii = pair<int, int>; void solve() { int n; cin >> n; vector<pii> a(n); for (auto &[d, s]: a) cin >> d >> s; sort(a.begin(), a.end()); int l = 0, r = inf, res = -1; for (int mid, flag; l <= r;) { mid = (l + r) >> 1, flag = 1; for (auto [d, s]: a) { if (d > mid) break; if ((mid - d) * 2 < s) continue; flag = 0; break; } if( flag ) res = mid , l = mid + 1; else r = mid - 1; } cout << res << "\n"; } int32_t main() { int t; cin >> t; while (t--) solve(); return 0; }

3|0C. Non-coprime Split


只要区间中有大于 2 的偶数一定可以,对于区间内只有奇数的情况就暴力的判一下。

#include <bits/stdc++.h> using namespace std; #define int long long constexpr int mod = 1e9 + 7, inf = 1e18; using i64 = long long; using pii = pair<int, int>; void solve() { int l, r; cin >> l >> r; if (r <= 3) return cout << "-1\n", void(); if (l == r) { if (r % 2 == 0) { cout << 2 << " " << r - 2 << "\n"; return; } for (int i = 2; i * i <= r; i++) if (r % i == 0) { cout << i << " " << r - i << "\n"; return; } return cout << "-1\n", void(); } if (r & 1) r--; cout << 2 << " " << r - 2 << "\n"; return; } int32_t main() { int t; cin >> t; while (t--) solve(); return 0; }

4|0D. Plus Minus Permutation


算出来最多能取多少个数字,贪心的取最大的即可。

#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int n , a , b , c; cin >> n >> a >> b ; c = lcm( a , b ); a = n / a , b = n / b , c = n / c; a -= c , b -= c; int res = ( 2 * n - a + 1 ) * a / 2 - b * ( 1 + b ) / 2; cout << res << "\n"; return ; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int TC; for( cin >> TC ; TC ; TC --) solve(); return 0; }

5|0E. Data Structures Fan


看到比较懂 DS 的佬是线段树写的。我的做法是前缀异或和,求区间取反操作就直接把这一段直接异或到答案上即可。

#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int n , res = 0; cin >> n; vector<int> a(n+1); for( int i = 1 ; i <= n ; i ++ ) cin >> a[i]; string s; cin >> s; for( int i = 1 ; i <= n ; i ++ ) if( s[i-1] == '1' ) res ^= a[i]; for( int i = 2 ; i <= n ; i ++ ) a[i] ^= a[i-1]; int q; cin >> q; for( int op , x , y ; q ; q -- ){ cin >> op >> x; if( op == 1 ){ cin >> y; res ^= (a[y] ^ a[x-1]); }else { if( x == 1 ) cout << res << " "; else cout << ( res ^ a[n] ) << " "; } } cout << "\n"; return ; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int TC; for( cin >> TC ; TC ; TC --) solve(); return 0; }

6|0F. Selling a Menagerie


这个图本身是一个内向基环树森林,所以除了每一颗基环树,只有环上的一个点无法取到两倍贡献,自然这个点就是权值最小的点,所以我们找到每一个环上的这个点,然后删掉他对应的边,最后求一下拓扑序就是答案。

#include <bits/stdc++.h> using namespace std; #define int long long constexpr int mod = 1e9 + 7, inf = 1e18; using i64 = long long; using pii = pair<int, int>; void solve() { int n, it; cin >> n; vector<int> a(n + 1), vis(n + 1), c(n + 1), inner(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) cin >> c[i]; auto dfs = [&it, &vis, a, c, n](auto &&self, int x, int tag) -> void { if (vis[x] == 0) vis[x] = tag; else if (vis[x] == tag) { if (it == 0 or c[x] < c[it]) it = x; vis[x] = tag + n; } else return; self(self, a[x], tag); }; for (int i = 1; i <= n; i++) { if (vis[i]) continue; it = 0, dfs(dfs, i, i), a[it] = 0; } for (int i = 1; i <= n; i++) if (a[i]) inner[a[i]]++; queue<int> q; for (int i = 1; i <= n; i++) if (inner[i] == 0) q.push(i); for (int x; !q.empty();) { x = q.front(), q.pop(); cout << x << " "; x = a[x]; if (x == 0) continue; if (--inner[x] == 0) q.push(x); } cout << "\n"; return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int t; cin >> t; while (t--) solve(); return 0; }

7|0G. Replace With Product


有几个特殊的性质,前缀后缀的1一定不会被选。其次 1 一定不会做端点,所以我们可以先判断一下,去掉前缀后乘积是否大于和,大于就可以直接输出答案。否则的话,我们枚举非1的点最为端点,然后计算一下即可。为了快速计算,可以提前处理前缀和前缀积。

#include <bits/stdc++.h> using namespace std; #define int long long using i64 = long long; using i128 = __int128; using pii = pair<int, int>; constexpr int mod = 1e9 + 7, inf = 1e18; constexpr i128 lim = 1e15; void solve() { int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; int l = 1, r = n; while (l <= r and a[l] == 1) l++; while (l <= r and a[r] == 1) r--; if (l > r) { cout << "1 1\n"; return; } bool flag = false; i128 mul = 1; for (int i = 1; i <= n and flag == false; i++){ if (mul * (i128)a[i] > lim) flag = true; mul *= (i128)a[i]; } if (flag) { cout << l << " " << r << "\n"; return; } vector<int> s1(n + 1), s2(n + 1), can; s2[0] = 1; for (int i = 1; i <= n; i++) { s1[i] = s1[i - 1] + a[i]; s2[i] = s2[i - 1] * a[i]; if (a[i] > 1) can.push_back(i); } int ans = s1[n]; pii res = make_pair(1, 1); for (auto i: can) for (auto j: can) { if (j > i) break; int t = s2[i] / s2[j - 1] + s1[n] - s1[i] + s1[j - 1]; if (t > ans) ans = t, res = make_pair(j, i); } cout << res.first << " " << res.second << "\n"; return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int t; cin >> t; while (t--) solve(); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17691872.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示