1157 字
3 分钟
Codeforces_Round_1107(Div. 3)(A~D题)
2026-07-15
浏览量 4 · 访客 2

题目链接:https://codeforces.com/contest/2244

A - Iskander and Drawings#

算是模拟题,我们直接暴力找出最大连续的#'\#'子串再判断最长时间就可以了。我这里的实现思路是先判断有没有#'\#',没有直接输出00返回,有就初始化最大长度max_lenmax\_len11,然后遍历字符串找出最大连续的#'\#'子串长度。最后根据最大长度计算出最大时间。(奇数除2211偶数除22

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
void solved() {
int n; cin >> n;
string s; cin >> s;
int max_len = 1;
int len = 1; bool f = false;
for(int i = 0; i < n;i++)
if(s[i] == '#') f = true;
if(!f) {cout << 0 << endl; return;}
for(int i = 1; i < n;i++){
if(s[i - 1] == '#' && s[i] == '#')
len++;
else len = 1;
max_len = max(max_len, len);
}
cout << ((max_len % 2) ? max_len / 2 + 1 : max_len / 2) << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) {
solved();
}
return 0;
}

B - Nikita and Books#

这题我们根据题意可以知道,对应一个数nn,使其满足严格单调递增的ana_n数组,至少需要1,2,3,4,5....n1,n1,2,3,4,5....n-1,n这样的排列。也就是数组元素之和要至少大于等于 n(n+1)2\frac{n(n + 1)}{2}。(第一个条件)我们可以发现大于等于这个值的数无论如何都能构造出一个满足条件的数组。
然后我们再注意到题目的另外一个关键条件:书本的传递是只能从左向右的。这其实说明一个情况,如果前kk项的和无法满足大于k(k+1)2\frac{k(k + 1)}{2},(第二个条件)那么整个数组也就无法严格单调递增了,所以最终能满足条件的数组必须要满足这两个条件。(实际上第二个条件也就是第一条件的严苛版)
我们在实现时就在遍历时就判断当前的前缀和是否大于等于i(i+1)2\frac{i(i + 1)}{2}即可。(这里我在实现时还复杂了些,第一处特判NONO的部分可以删去。)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
int a[200010];
void solved() {
int n; cin >> n;
ll sum = 0, pre = 0;
ll cmp = n * (1 + n) / 2;
for(int i = 1; i <= n;i++){
cin >> a[i]; sum += a[i];
}
if(sum < cmp){cout << "NO" << endl; return;}
sum = 0;
for(int i = 1; i <= n;i++){
pre += a[i];
sum += i;
if(pre < sum){
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) {
solved();
}
return 0;
}

C - Stepan and Permutation#

这题我们可以转化一下题意,实际上能交换的两个元素就是需要满足两者之间的距离为xx或者yy就可以交换了。这里我们还需要理解的就是这个条件还可以转化得更加细一些:只要满足距离g=gcd(x,y)g = gcd(x, y)(最大公因数)的两个元素都可以交换元素,这个是很显而易见的,因为我们完全可以通过两个或者更多次操作实现这个更短距离gg的交换。
因此,根据这个最短交换距离gg,我们可以判断一个元素最终是否能回到它作为排列的位置。也就是需要他当前的位置iip[i]p[i]之差要是gg的倍数(或者就已经在原位了),那么它就是可达的,否则就不可达。所以我们就只需要判断这个条件即可,如果存在p[i]p[i]ii不满足这个条件就直接输出NONO,都满足就输出YESYES

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
int p[200010];
void solved() {
int n, x, y;
cin >> n >> x >> y;
for(int i = 1; i <= n;i++) cin >> p[i];
int g = gcd(x, y);
for (int i = 1; i <= n; i++) {
if ((p[i] - i) % g != 0) {
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) {
solved();
}
return 0;
}

D - Yaroslav and Productivity#

这题我们不妨以bib_i作为边界划分每个区间:[1,b1],[b1+1,b2],...[bn1+1,bn],[bn+1,n][1, b_1], [b_1 + 1, b_2], ... [b_{n - 1} + 1, b_n], [b_n + 1, n]。那么我们就会发现,每个区间的和只有两种状态,要么是正要么是负。除了最后一个区间[bn+1,n][b_n + 1, n]我们无法翻转操作之外,其他区间我们都希望尽可能取到正。(因为我们需要找出一种操作所有元素之和的最大值最大)
而事实上,我们完全可以做到让所有的区间为正。我们不妨从最右边的区间[bn1+1,bn][b_{n - 1} + 1, b_n]开始,它的正反只由bnb_n决定,所以我们一定可以让它取得正。我们假设翻转了前nn项的所有区间定义opn=1op_n = 1,反则设置为00。然后看到[bn2+1,bn1][b_{n - 2} + 1, b_{n - 1}],它的正反会受到bnb_nbn1b_{n - 1}的共同影响,但我们完全可以根据已经设定好的opnop_n适当调整opn1op_{n - 1}使得这个区间也取到正:
假设[bn+1,n][b_n + 1, n]需要翻转才能取到正那么opn=1op_n = 1,并且[bn2+1,bn1][b_{n - 2} + 1, b_{n - 1}]不需要翻转才能取到正那么opn1=1op_{n - 1} = 1,这样才能抵消[bn+1,n][b_n + 1, n]的翻转。因此后面这两个区间的状态对前面区间的操作的影响其实是opnopn1=0op_n \bigoplus op_{n - 1} = 0也就是没翻转前面的n2n - 2个区间的。所以传递给前面的状态就是opn1op_{n - 1}重赋值为00(未翻转前面的区间),那么opn2op_{n - 2}就可以再根据这个opn1op_{n - 1}来判断是否需要翻转。
以此类推前面的区间的opiop_i,同样可以根据后面传递上来的opi+1op_{i + 1}的状态来取1100,使得最终每个区间都取到正。
所以我们最终的实现只需要将这些划分的区间的正值相加,再加上最后一段无法操作的区间[bn+1,n][b_n + 1, n]的原值即是最终答案了。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
void solved() {
int n, m; cin >> n >> m;
vector<ll> prefix(n + 1, 0);
for(int i = 1; i <= n;i++){
ll x; cin >> x;
prefix[i] = prefix[i - 1] + x;
}
vector<int> b(m, 0);
for(int i = 0; i < m;i++) cin >> b[i];
sort(b.begin(), b.end());
ll ans = 0; int last_end = 0;
for(int it : b){
ll sum = prefix[it] - prefix[last_end];
last_end = it;
ans += abs(sum);
}
ans += prefix[n] - prefix[last_end];
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) {
solved();
}
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Codeforces_Round_1107(Div. 3)(A~D题)
https://mkrari.cn/posts/cf_round_1109_div3/
作者
Mkrari
发布于
2026-07-15
许可协议
CC BY-NC-SA 4.0