Codeforces Round 960 (Div. 2)
写在前面
比赛地址:https://codeforces.com/contest/1990
依旧是红温温温温温温温温温温场。
AB 每题都吃了两发,爽!D 到最后也没调出来赛后五分钟看出来哪挂了,爽!又要掉一百分了,爽!
所有错误都是每题多看两眼就能找到的但就是没多看两眼。
妈的傻逼一天天的在这干啥啊、、、急成这个逼样子还是急着投胎算了。
A
手玩。
操作等价于选择某个权值的第一个数,并将在此之前所有数全部删除。
先考虑只有一种权值的情况。显然此时若 为奇数,则先手必胜,否则先手必败。
然后考虑多种权值。发现若所有权值的出现次数均为偶数,则先手必败,否则先手仅需选择最大的出现次数为奇数的权值,即可令后手进入必败状态。
于是仅需检查是否有一种权值出现次数为奇数即可。
复制复制// /* 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
构造。
显然应令 内全部为 1, 均为 -1。然后考虑令 和 的前后缀和均尽可能地小以符合题意。
发现仅需从 开始,分别向左右构造成 -1/1 交替的形式即可。此时 和 的任意前后缀和均不大于 1。且若 存在前缀和为 1 则 和为 0;若 存在后缀和为 1 则 和为 0。而在 内至少会获得 +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。
于是先暴力模拟两轮记录贡献和,然后求得每种权值的出现次数,再降序枚举每种权值(也即每轮删数的顺序),统计删去该权值的各轮的贡献之和即可。
总时间复杂度 级别。
// /* 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
手玩,贪心。
发现使用 矩阵的操作 1 大部分情况下是不值的,对某两行使用两次操作 1 一定不优于两次操作 2。
手玩下可以发现如下结论:
- 使用一次操作 2 等于对下方所有行消除之前进行的操作 1 的影响,于是仅需考虑每次连续使用操作 1 的影响。
- 使用操作 1 被覆盖的行黑色数量一定不会大于 4,否则不优。
- 连续使用操作 1 时,若使用了 次则一定会使 行被全部覆盖,否则不优。
- 连续使用操作 1 时,被覆盖的第一行黑色数量一定不会大于 2,否则不优。
- 由结论 1234,连续使用操作 1 时,第一次操作 1 覆盖的范围一定是 ,第二次一定是 ,第三次一定是 ,……直至第 行黑色数量大于 4,或使用操作 1 后无法覆盖到第 行,此时对第 行进行一次操作 2 一定不会更劣。然后从第 行开始重复上述过程。
根据结论 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
交互,
写在最后
学到了什么:
- 急你马呢
- 急你马呢急你马呢
- 急你马呢急你马呢急你马呢
- 急你马呢急你马呢急你马呢急你马呢
- 急你马呢急你马呢急你马呢急你马呢急你马呢
- 急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢
- 急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢急你马呢
我操不想活了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧