Codeforces Round #875 (Div. 2) A-D
A
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) { int x; cin >> x; cout << n - x + 1 << " \n"[i == 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> using namespace std; using ll = long long; int lena[400007], lenb[400007]; bool solve() { int n; cin >> n; for (int i = 1;i <= 2 * n;i++) lena[i] = lenb[i] = 0; int pre = 0, len = 0; for (int i = 1;i <= n;i++) { int x; cin >> x; if (x != pre) { lena[pre] = max(lena[pre], len); len = 0; pre = x; } len++; } lena[pre] = max(lena[pre], len); len = 0; pre = 0; for (int i = 1;i <= n;i++) { int x; cin >> x; if (x != pre) { lenb[pre] = max(lenb[pre], len); len = 0; pre = x; } len++; } lenb[pre] = max(lenb[pre], len); int ans = 0; for (int i = 1;i <= 2 * n;i++) ans = max(ans, lena[i] + lenb[i]); cout << ans << '\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
题意
一棵树有 个节点,一开始只有根节点 。
现在给出加边的顺序,每次操作按顺序从头到尾依次加边。
一次操作中,当且仅当一条边还没被加,且一个端点已经存在,才能加这条边。
问要最少操作几次,所有边才能都被加入。
题解
知识点:树形dp,DFS。
可以用树型dp求出每个点出现需要的最少操作次数。
点的出现时间取决于边的顺序,我们将边的顺序记录到边权中,dfs过程中将边权当作孩子的出现时间。
若一个点出现时间比它孩子出现时间要晚,那么它孩子出现需要的操作次数就是它的操作次数加 ,否则可以在同一次操作中处理完。
设 表示节点 出现需要的最少操作次数, 表示节点 的出现时间,转移即上述所说。
最后答案为 的最大值。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; vector<pair<int, int>> g[200007]; int rk[200007], f[200007]; void dfs(int u, int fa) { for (auto [v, w] : g[u]) { if (v == fa) continue; rk[v] = w; f[v] = f[u] + (w < rk[u]); dfs(v, u); } } bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) g[i].clear(); for (int i = 1;i <= n - 1;i++) { int u, v; cin >> u >> v; g[u].push_back({ v,i }); g[v].push_back({ u,i }); } rk[1] = n; dfs(1, 0); cout << *max_element(f + 1, f + n + 1) << '\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
题意
给定长度为 的数组 ,求出所有满足 的 对数。
题解
知识点:数学,枚举。
注意到 ,因此 ,即 。此时,我们设 ,那么 。
因此,我们先将 打包,以 为关键字从小到大排序,这是为了之后从左到右枚举 时,保证满足 这个条件,此时 的范围才是 。
随后,我们枚举 ,作为一轮枚举中 满足的值。接下来,从左到右枚举 ,有 ,其中 就是在 时我们希望的 ,而 的贡献即为 满足 的位置中,出现过的 的位置数。
因此,我们在过程中记录 满足 的位置中,出现过的 的个数 。那么,当 时, 即为 的贡献。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; pair<int, int> c[200007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++)cin >> c[i].first; for (int i = 1;i <= n;i++)cin >> c[i].second; sort(c + 1, c + n + 1); ll ans = 0; for (int A = 1;A * A <= 2 * n;A++) { vector<int> cnt(n + 1); for (int i = 1;i <= n;i++) { auto [a, b] = c[i]; int B = A * a - b; if (1 <= B && B <= n) ans += cnt[B]; if (a == A) cnt[b]++; } } cout << ans << '\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/17558351.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2022-07-16 CF590C Three States
2022-07-16 NC235247 Sramoc问题
2022-07-16 NC24605 [USACO 2011 Ope S]Corn Maze
2022-07-16 NC19975 [HAOI2008]移动玩具
2022-07-16 NC17872 CSL的校园卡
2022-07-16 NC15445 wyh的吃鸡
2022-07-16 NC15136 迷宫