ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022牛客暑期多校训练营3-A.Ancestor(LCA)

2022-07-26 18:35:06  阅读:130  来源: 互联网

标签:pre suf fa int 多校 牛客 2022 LCA include


题目传送门:https://ac.nowcoder.com/acm/contest/33188/A

题意: • 给出两棵编号 1-n 的树 A B , A B 树上每个节点均有一个权值,给出 k 个关键点的编号,问有多 少种方案使得去掉恰好一个关键点使得剩余关键点在树 A 上 LCA 的权值大于树 B 上 LCA 的权值。

思路:预处理出关键点序列的在树 A B 上的前缀 LCA 和后缀 LCA ,枚举去掉的关键节点并使用前后缀 LCA 算出剩余节点的 LCA 比较权值即可。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<map>
  6 #include<queue>
  7 #include<set>
  8 #include<cmath>
  9 #include<list>
 10 #include<cstring>
 11 #include<string>
 12 #define ll long long
 13 #define ull unsigned long long
 14 #define inf 0x3f3f3f3f
 15 #define inff 0x7fffffff
 16 using namespace std;
 17 const int N = 100000 + 10;
 18 
 19 int x[N];
 20 int n, k;
 21 
 22 struct tree {
 23 
 24     int fa[N][31], dep[N];
 25     vector<int>G[N];
 26     int pre[N], suf[N];
 27 
 28     void add(int u, int v) {
 29         G[u].push_back(v);
 30     }
 31     void dfs(int x, int pre) {
 32 
 33         fa[x][0] = pre;
 34         dep[x] = dep[pre] + 1;
 35         for (int i = 1; i <= 20; i++) {
 36             fa[x][i] = fa[fa[x][i - 1]][i - 1];
 37         }
 38         for (int i = 0; i < G[x].size(); i++) {
 39             if (G[x][i] != pre) dfs(G[x][i], x);
 40         }
 41 
 42     }
 43     int lca(int x, int y) {
 44 
 45         if (dep[x] < dep[y]) swap(x, y);
 46         for (int i = 20; i >= 0; i--) {
 47             if ((1 << i) <= dep[x] - dep[y]) x = fa[x][i];
 48         }
 49         if (x == y) return x;
 50         for (int i = 20; i >= 0; i--) {
 51             if (fa[x][i] != fa[y][i]) {
 52                 x = fa[x][i];
 53                 y = fa[y][i];
 54             }
 55         }
 56 
 57         return fa[x][0];
 58     }
 59     void do_work() {
 60         dfs(1, 0);
 61         pre[1] = x[1];
 62         for (int i = 2; i <= k; i++) {
 63             pre[i] = lca(pre[i - 1], x[i]);
 64         }
 65         suf[k] = x[k];
 66         for (int i = k - 1; i >= 1; i--) {
 67             suf[i] = lca(suf[i + 1], x[i]);
 68         }
 69     }
 70     int get_lca(int i) {
 71         if (i == 1) return suf[2];
 72         if (i == k) return pre[k - 1];
 73         return lca(pre[i - 1], suf[i + 1]);
 74     }
 75 
 76 }treeA, treeB;
 77 
 78 
 79 int wA[N], wB[N];
 80 
 81 int main() {
 82 
 83     ios::sync_with_stdio(false);
 84     cin.tie(0), cout.tie(0);
 85     cin >> n >> k;
 86     for (int i = 1; i <= k; i++) {
 87         cin >> x[i];
 88     }
 89     for (int i = 1; i <= n; i++) {
 90         cin >> wA[i];
 91     }
 92     for (int i = 2; i <= n; i++) {
 93         int u;
 94         cin >> u;
 95         treeA.add(u, i);
 96     }
 97     for (int i = 1; i <= n; i++) {
 98         cin >> wB[i];
 99     }
100     for (int i = 2; i <= n; i++) {
101         int u;
102         cin >> u;
103         treeB.add(u, i);
104     }
105     int ans = 0;
106     treeA.do_work();
107     treeB.do_work();
108     for (int i = 1; i <= k; i++) {
109         int la = treeA.get_lca(i);
110         int lb = treeB.get_lca(i);
111         if (wA[la] > wB[lb]) ans++;
112     }
113     cout << ans << "\n";
114 
115     return 0;
116 }

 

 

标签:pre,suf,fa,int,多校,牛客,2022,LCA,include
来源: https://www.cnblogs.com/wabi/p/16522076.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有