直接sort排序,用&加快读取速度即可
AC代码:
#include <bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<n;i++) using namespace std; using LL = long long; bool cmp(string &a, string &b) { return a + b < b + a; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<string> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } sort(a.begin(), a.end(), cmp); for (int i = 0; i < n; i++) { cout << a[i]; } cout << '\n'; return 0; }
题目大意是给定两棵树,每个点都有各自的点权,给出k个关键点,删除某一个关键点以后,A树的剩下所有关键点的LCA的点权大于B树剩下所有关键点的LCA的点权的个数
一种思路:枚举每个关键点,假设它就是被删除的,求剩下的所有关键点的LCA,可知LCA可以累积计算,所以先预处理出两棵树各自的前缀LCA和后缀LCA,最后枚举k个关键点,这时只需要求前缀LCA和后缀LCA去掉这个点以后的LCA即可
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int n, k, z[100010]; struct Tree { int f[100010][25], dep[100010], pre[100010], suf[100010]; vector<int> G[100010]; void init() { dfs(1, 0); for (int i = 1; i <= k; i++) { if (i == 1) { pre[i] = z[i]; } else { pre[i] = lca(pre[i - 1], z[i]); } } for (int i = k; i >= 1; i--) { if (i == k) { suf[i] = z[i]; } else { suf[i] = lca(suf[i + 1], z[i]); } } } void dfs(int u, int fa) { dep[u] = dep[fa] + 1; f[u][0] = fa; for (int i = 1; (1 << i) < dep[u]; i++) { f[u][i] = f[f[u][i - 1]][i - 1]; } for (auto v : G[u]) { if (v != fa) { dfs(v, u); } } } int lca(int x, int y) { if (dep[x] > dep[y]) { swap(x, y); } for (int i = 20; i >= 0; i--) { if (dep[x] <= dep[y] - (1 << i)) { y = f[y][i]; } } if (x == y) { return x; } for (int i = 20; i >= 0; i--) { if (f[x][i] == f[y][i]) { continue; } x = f[x][i]; y = f[y][i]; } return f[x][0]; } }a, b; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> k; for (int i = 1; i <= k; i++) { cin >> z[i]; } vector<int> x(n + 1), y(n + 1); for (int i = 1; i <= n; i++) { cin >> x[i]; } for (int i = 2; i <= n; i++) { int fa; cin >> fa; a.G[fa].push_back(i); a.G[i].push_back(fa); } for (int i = 1; i <= n; i++) { cin >> y[i]; } for (int i = 2; i <= n; i++) { int fa; cin >> fa; b.G[fa].push_back(i); b.G[i].push_back(fa); } a.init(); b.init(); int ans = 0; for (int i = 1; i <= k; i++) { if (i == 1) { if (x[a.suf[i + 1]] > y[b.suf[i + 1]]) { ans++; } } else if (i == k) { if (x[a.pre[i - 1]] > y[b.pre[i - 1]]) { ans++; } } else { if (x[a.lca(a.pre[i - 1], a.suf[i + 1])] > y[b.lca(b.pre[i - 1], b.suf[i + 1])]) { ans++; } } } cout << ans << '\n'; return 0; }
“蔚来杯“2022牛客暑期多校训练营3 C、A
于 2022-08-02 10:08:02 首次发布
这篇博客主要介绍了两个C++编程问题的解决方案。一是使用排序和位运算优化读取速度,二是解决树的最近公共祖先(LCA)问题,涉及前缀LCA和后缀LCA的预处理及动态计算。文章提供了AC代码示例,展示了如何在删除特定关键点后,比较两棵树剩余部分的LCA点权大小。
摘要由CSDN通过智能技术生成