Codeforces Round 895 (Div. 3)
A. 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;
}
B. 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;
}
C. 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;
}
D. 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;
}
E. 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;
}
F. 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;
}
G. 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;
}
标签:
CodeForces
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法