Codeforces Global Round 23 A-D
A
题解
知识点:贪心,构造。
注意到有 就一定能构造。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; bool solve() { int n, k; cin >> n >> k; bool ok = 0; for (int i = 1;i <= n;i++) { int x; cin >> x; ok |= x; } if (ok) cout << "YES" << '\n'; else cout << "NO" << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
B
题解
知识点:枚举,双指针。
用对撞指针,枚举左侧 和 右侧 ,一次操作能消除一对。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[100007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; int l = 1, r = n; int cnt = 0; while (l <= r) { while (l <= r && a[l] == 0)l++; while (l <= r && a[r] == 1)r--; if (l <= r) { l++; r--; cnt++; } } cout << cnt << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
C
题解
知识点:枚举。
容易发现,我们可以通过操作将序列变成非减序列,只要我们从左到右操作每组 的 ,使 。这样的相邻数对之差大于 的不会超过 组,即第 次操作修改的一定小于等于 ,因此我们一定可以通过 次操作修改所有这样的数对。
把所有相邻两数的差带着下标从小到大排序输出下标就行。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[100007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; vector<pair<int, int>> v; v.push_back({ 0,1 }); for (int i = 2;i <= n;i++) { v.push_back({ a[i - 1] - a[i], i }); } sort(v.begin(), v.end()); for (auto [i, j] : v) cout << j << ' '; cout << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
D
题解
知识点:树形dp,贪心。
此题重点在于如何分配路径到子节点。
显然,为了保证子节点路径数至多相差 ,若父节点有 或 条路径,那么 个子节点可能的路径数只有 或 。
- 和 时,显然成立。
- 时, 能被整除时显然成立。
- 时, 不能被整除时 一定能被整除,但只有 一种合法情况, 有 或 两种,同样成立。
我们知道了子节点可能分配到路径后,对分配方法进行dp就行。
设 ,表示对于节点 的子树, 具有路径数为 或 时,子树的总贡献。对于 ,先加上 本身的贡献,以及子节点 路径数为 的一种贡献,即 ,这是子节点都能分配到的。
然后,对于 ,可以给 个子节点多分配一条路径;对于 可以给 个子节点多分配一条路径。这些子节点的贡献可以加一个增量 ,我们按照这个增量排序,就能找到增量最大的几个子节点,我们给它们分配即可。
最后输出 ,根节点没有多一条路径的选择。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; vector<int> g[200007]; int s[200007]; ll f[200007][2]; void dfs(int u, int p) { f[u][0] = 1LL * p * s[u]; f[u][1] = f[u][0] + s[u]; if (!g[u].size()) return; vector<ll> tb; for (auto v : g[u]) { dfs(v, p / g[u].size()); f[u][0] += f[v][0]; f[u][1] += f[v][0]; tb.push_back(f[v][1] - f[v][0]); } sort(tb.begin(), tb.end(), [&](ll a, ll b) {return a > b;}); int r = p % g[u].size(); for (int i = 0;i < r;i++) f[u][0] += tb[i]; for (int i = 0;i <= r;i++) f[u][1] += tb[i]; } bool solve() { int n, k; cin >> n >> k; for (int i = 1;i <= n;i++) g[i].clear(); for (int i = 2;i <= n;i++) { int p; cin >> p; g[p].push_back(i); } for (int i = 1;i <= n;i++) cin >> s[i]; dfs(1, k); cout << f[1][0] << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16840730.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧