Codeforces Round 960 (Div. 2)

写在前面

比赛地址:https://codeforces.com/contest/1990

依旧是红温温温温温温温温温温场。

AB 每题都吃了两发,爽!D 到最后也没调出来赛后五分钟看出来哪挂了,爽!又要掉一百分了,爽!

所有错误都是每题多看两眼就能找到的但就是没多看两眼。

妈的傻逼一天天的在这干啥啊、、、急成这个逼样子还是急着投胎算了。

A

手玩。

操作等价于选择某个权值的第一个数,并将在此之前所有数全部删除。

先考虑只有一种权值的情况。显然此时若 n 为奇数,则先手必胜,否则先手必败。

然后考虑多种权值。发现若所有权值的出现次数均为偶数,则先手必败,否则先手仅需选择最大的出现次数为奇数的权值,即可令后手进入必败状态。

于是仅需检查是否有一种权值出现次数为奇数即可。

复制复制
//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
//freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
int n; std::cin >> n;
int cnt[100] = {0};
for (int i = 1; i <= n; ++ i) {
int a; std::cin >> a;
++ cnt[a];
}
int flag = 0;
for (int i = n; i; -- i) {
if (cnt[i] % 2 == 1) flag = 1;
}
std::cout << (flag ? "YES\n" : "NO\n");
}
return 0;
}

B

构造。

显然应令 [y,x] 内全部为 1,y1,x+1 均为 -1。然后考虑令 [1,y1][x+1,n] 的前后缀和均尽可能地小以符合题意。

发现仅需从 y1,x+1 开始,分别向左右构造成 -1/1 交替的形式即可。此时 [1,y1][x+1,n] 的任意前后缀和均不大于 1。且若 [1,y1] 存在前缀和为 1 则 [1,y1] 和为 0;若 [x+1,n] 存在后缀和为 1 则 [x+1,n] 和为 0。而在 [y,x] 内至少会获得 +2 的贡献,则上述构造一定合法。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 1e5 + 10;
//=============================================================
int n, x, y, ans[kN];
//=============================================================
//=============================================================
int main() {
//freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> n >> x >> y;
// int a = x - 1, b = y - x - 1, c = n - x;
ans[x] = ans[y] = 1;
for (int i = y; i <= x; ++ i) ans[i] = 1;
for (int i = y - 1, j = -1; i; -- i, j = -j) ans[i] = j;
for (int i = x + 1, j = -1; i <= n; ++ i, j = -j) ans[i] = j;
for (int i = 1; i <= n; ++ i) std::cout << ans[i] << " ";
std::cout << "\n";
}
return 0;
}

C

模拟,暴力。

先手玩一下。前两次操作没什么规律,但发现从第二次操作开始,数列一定为单调递增,且除了最大的权值外每种权值至少出现 2 次,且每次操作对数列的影响均为使数列整体右移一位,删去最后一个数并在前面补 0。

于是先暴力模拟两轮记录贡献和,然后求得每种权值的出现次数,再降序枚举每种权值(也即每轮删数的顺序),统计删去该权值的各轮的贡献之和即可。

总时间复杂度 O(n) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, a[kN], cnt[kN];
LL ans;
//=============================================================
void solve() {
for (int i = 0; i <= n; ++ i) cnt[i] = 0;
int mad = 0;
for (int i = 1; i <= n; ++ i) {
ans += a[i];
++ cnt[a[i]];
if (cnt[a[i]] >= 2 && a[i] > mad) mad = a[i];
a[i] = mad;
}
}
LL sum(int L_, int R_) {
return 1ll * (L_ + R_) * (R_ - L_ + 1ll) / 2ll;
}
void solve1() {
LL delta = 0;
for (int i = 0; i <= n; ++ i) cnt[i] = 0;
for (int i = 1; i <= n; ++ i) delta += a[i], ++ cnt[a[i]];
for (int i = n; i; -- i) {
if (cnt[i] == 0) continue;
ans += 1ll * cnt[i] * delta - sum(1, cnt[i] - 1) * i;
delta -= 1ll * cnt[i] * i;
}
}
//=============================================================
int main() {
// freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> n;
ans = cnt[0] = 0;
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
cnt[i] = 0;
}
solve();
solve();
solve1();
std::cout << ans << "\n";
}
return 0;
}
/*
1
3
2 2 3
*/

D

手玩,贪心。

发现使用 2×2 矩阵的操作 1 大部分情况下是不值的,对某两行使用两次操作 1 一定不优于两次操作 2。

手玩下可以发现如下结论:

  1. 使用一次操作 2 等于对下方所有行消除之前进行的操作 1 的影响,于是仅需考虑每次连续使用操作 1 的影响。
  2. 使用操作 1 被覆盖的行黑色数量一定不会大于 4,否则不优。
  3. 连续使用操作 1 时,若使用了 k 次则一定会使 k+1 行被全部覆盖,否则不优。
  4. 连续使用操作 1 时,被覆盖的第一行黑色数量一定不会大于 2,否则不优。
  5. 由结论 1234,连续使用操作 1 时,第一次操作 1 覆盖的范围一定是 (x,1),(x,2),第二次一定是 (x+1,3),(x+1,4),第三次一定是 (x+2,1),(x+2,2),……直至第 x+k 行黑色数量大于 4,或使用操作 1 后无法覆盖到第 x+k+1 行,此时对第 x+k 行进行一次操作 2 一定不会更劣。然后从第 x+k+1 行开始重复上述过程。

根据结论 45,仅需从第一行开始贪心地操作即可。若某行满足进行第一次操作 1 的条件,则连续进行操作 1 直至不满足条件,再换用一次操作 2,再从下一行开始重复上述过程。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, a[kN];
//=============================================================
int solve(int now_, int left_, int right_) {
if (now_ > n) return 0;
if (a[now_] <= 0) return solve(now_ + 1, 0, 0); //此行不需操作
if (a[now_] <= 2) {
if (left_) return solve(now_ + 1, 0, 0); //左侧两个已被覆盖,则不需操作此行
return solve(now_ + 1, 1, 0) + 1; //对此行进行操作 1,不会更劣
}
if (a[now_] <= 4) {
if (right_) return solve(now_ + 1, 1, 0) + 1; //右侧两个已被覆盖,对左侧操作
if (left_) return solve(now_ + 1, 0, 1) + 1; //左侧两个已被覆盖,对右侧操作
//若无覆盖,对此行操作 2,不会更劣。
}
return solve(now_ + 1, 0, 0) + 1; //此行操作 2
}
//=============================================================
int main() {
// freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> n;
for (int i = 1; i <= n; ++ i) std::cin >> a[i];
std::cout << solve(1, 0, 0) << "\n";
}
return 0;
}
/*
1
4
3 2 1 0
1
4
2 4 4 2
1
3
2 3 5
1
6
2 4 4 4 4 2
*/

E

交互,

写在最后

学到了什么:

  • 急你马呢
  • 急你马呢急你马呢
  • 急你马呢急你马呢急你马呢
  • 急你马呢急你马呢急你马呢急你马呢
  • 急你马呢急你马呢急你马呢急你马呢急你马呢
  • 急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢
  • 急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢

我操不想活了。

posted @   Luckyblock  阅读(565)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示