蔚来杯2022牛客暑期多校训练营3 AC
A
题解
知识点:LCA。
队友写的,俺不会qwq。预处理出关键点序列的在树A B上的前缀LCA和后缀LCA,枚举去掉的关键节点并使用前后缀LCA算出剩余节点的LCA比较权值即可。
时间复杂度
空间复杂度
代码
#include<bits/stdc++.h> #define N 400010 #define inf 0x7fffffff using namespace std; int n, m, dep[N], fa[N][23], first[N], cnt, ans, w[N]; int ss[N], k, maxk_A[2], mink_A[2], maxx_A[2], minn_A[2] = { inf,inf }, dfsx[N], t; int maxk_B[2], mink_B[2], maxx_B[2], minn_B[2] = { inf,inf }; struct node { int v, next; }edge[N]; void add(int u, int v) { edge[++cnt] = (node){ v,first[u] }; first[u] = cnt; } void dfs(int u, int fath) { dep[u] = dep[fath] + 1, fa[u][0] = fath, dfsx[u] = ++t; for (int i = 1;i <= (int)log2(dep[u]) + 1;i++) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (int i = first[u];i != 0;i = edge[i].next) { if (edge[i].v != fath) dfs(edge[i].v, u); } } int LCA(int x, int y) { if (dep[x] < dep[y]) swap(x, y); while (dep[x] > dep[y]) x = fa[x][(int)log2(dep[x] - dep[y])]; if (x == y) return x; for (int i = (int)log2(dep[x]);i >= 0;i--) { if (fa[x][i] != fa[y][i]) { x = fa[x][i]; y = fa[y][i]; } } return fa[x][0]; } int main() { scanf("%d%d", &n, &k); for (int i = 1;i <= k;i++) scanf("%d", &ss[i]); for (int i = 1;i <= n;i++) scanf("%d", &w[i]); for (int i = 1, x;i < n;i++) { scanf("%d", &x); add(i + 1, x), add(x, i + 1); } for (int i = 1;i <= n;i++) scanf("%d", &w[i + n]); for (int i = 1, x;i < n;i++) { scanf("%d", &x); add(i + 1 + n, x + n), add(x + n, i + 1 + n); } dfs(1, 0); t = 0, dfs(1 + n, 0); for (int i = 1;i <= k;i++) { if (dfsx[ss[i]] > maxx_A[0]) { maxk_A[1] = maxk_A[0], maxx_A[1] = maxx_A[0]; maxk_A[0] = ss[i], maxx_A[0] = dfsx[ss[i]]; } else if (dfsx[ss[i]] > maxx_A[1]) maxk_A[1] = ss[i], maxx_A[1] = dfsx[ss[i]]; if (dfsx[ss[i]] < minn_A[0]) { mink_A[1] = mink_A[0], mink_A[1] = minn_A[0]; mink_A[0] = ss[i], minn_A[0] = dfsx[ss[i]]; } else if (dfsx[ss[i]] < minn_A[1]) mink_A[1] = ss[i], minn_A[1] = dfsx[ss[i]]; } for (int i = 1;i <= k;i++) { if (dfsx[ss[i] + n] > maxx_B[0]) { maxk_B[1] = maxk_B[0], maxx_B[1] = maxx_B[0]; maxk_B[0] = ss[i], maxx_B[0] = dfsx[ss[i] + n]; } else if (dfsx[ss[i] + n] > maxx_B[1]) maxk_B[1] = ss[i], maxx_B[1] = dfsx[ss[i] + n]; if (dfsx[ss[i] + n] < minn_B[0]) { mink_B[1] = mink_B[0], minn_B[1] = minn_B[0]; mink_B[0] = ss[i], minn_B[0] = dfsx[ss[i] + n]; } else if (dfsx[ss[i] + n] < minn_B[1]) mink_B[1] = ss[i], minn_B[1] = dfsx[ss[i] + n]; } for (int i = 1;i <= k;i++) { int x_A, y_A, x_B, y_B; if (ss[i] != maxk_A[0]) x_A = maxk_A[0]; else x_A = maxk_A[1]; if (ss[i] != mink_A[0]) y_A = mink_A[0]; else y_A = mink_A[1]; if (ss[i] != maxk_B[0]) x_B = maxk_B[0]; else x_B = maxk_B[1]; if (ss[i] != mink_B[0]) y_B = mink_B[0]; else y_B = mink_B[1]; int a = LCA(x_A, y_A), b = LCA(x_B + n, y_B + n); if (w[a] > w[b]) ans++; } printf("%d", ans); return 0; } /* 5 2 3 4 6 6 3 4 6 1 2 2 4 7 4 5 7 7 1 1 3 2 */
C
题解
知识点:贪心,排序。
通过如下比较即可:
sort(s, s + n, [&](string &a, string &b) { return a + b < b + a; });
注意要用引用,否则可能过不去。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; string s[2000007]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 0;i < n;i++) cin >> s[i]; sort(s, s + n, [&](string &a, string &b) { return a + b < b + a; }); for (int i = 0;i < n;i++) cout << s[i]; cout << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16522842.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧