A - Problem A.Alkane
留坑。
B - Problem B. Beads
留坑。
C - Problem C. Calculate
留坑。
D - Problem D. Permutation
留坑。
E - Problem E. TeaTree
题意:每个点会存下任意两个以他为LCA的点对的GCD,求每个点存的GCD的最大值
思路:DSU on tree 用 set 维护子树中的因子,对于重儿子不要处理多次 每次查找的时候,枚举轻儿子中的因子
还有一种线段树合并的写法
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 6 int n; 7 vector <int> G[N], num[N]; 8 set <int> s; 9 int sz[N], son[N], cnt[N], cnt2[N], arr[N], ans[N], Max; 10 bool isbig[N]; 11 12 void Init() 13 { 14 for (int i = 1; i <= 100000; ++i) 15 { 16 int limit = sqrt(i); 17 for (int j = 1; j < limit; ++j) if (i % j == 0) 18 { 19 num[i].push_back(j); 20 num[i].push_back(i / j); 21 } 22 if (i % limit == 0) 23 { 24 num[i].push_back(limit); 25 if (limit * limit != i) num[i].push_back(i / limit); 26 } 27 } 28 } 29 30 void DFS(int u) 31 { 32 sz[u] = 1; 33 for (auto v : G[u]) 34 { 35 DFS(v); sz[u] += sz[v]; 36 if (son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v; 37 } 38 } 39 40 void update(int u) 41 { 42 for (auto it : num[arr[u]]) ++cnt[it]; 43 for (auto v : G[u]) if (!isbig[v]) update(v); 44 } 45 46 void work(int u, int fa) 47 { 48 for (auto it : num[arr[u]]) s.insert(it); 49 for (auto v : G[u]) if (!isbig[v]) work(v, fa); 50 } 51 52 void query(int u) 53 { 54 for (auto v : G[u]) if (!isbig[v]) 55 { 56 s.clear(); 57 work(v, u); 58 for (auto it : s) if (cnt[it] >= 1 || cnt2[it] >= 1) Max = max(Max, it); 59 for (auto it : s) ++cnt2[it]; 60 } 61 for (auto it : num[arr[u]]) if (cnt[it] >= 1 || cnt2[it] >= 1) Max = max(Max, it); 62 } 63 64 void clear(int u) 65 { 66 for (auto it : num[arr[u]]) cnt[it] = cnt2[it] = 0; 67 for (auto v : G[u]) clear(v); 68 } 69 70 void DSU(int u) 71 { 72 for (auto v : G[u]) if (v != son[u]) DSU(v); 73 if (son[u] != -1) { isbig[son[u]] = 1; DSU(son[u]); } 74 Max = -1; query(u); 75 ans[u] = Max; 76 if (isbig[u]) update(u); 77 if (son[u] != -1) isbig[son[u]] = 0; 78 if (!isbig[u]) clear(u); 79 } 80 81 int main() 82 { 83 Init(); 84 while (scanf("%d", &n) != EOF) 85 { 86 for (int i = 1; i <= n; ++i) G[i].clear(); 87 memset(son, -1, sizeof son); 88 memset(cnt, 0, sizeof cnt); 89 memset(cnt2, 0, sizeof cnt2); 90 Max = -1; s.clear(); 91 for (int i = 2, u; i <= n; ++i) 92 { 93 scanf("%d", &u); 94 G[u].push_back(i); 95 } 96 for (int i = 1; i <= n; ++i) scanf("%d", arr + i); 97 DFS(1); DSU(1); 98 for (int i = 1; i <= n; ++i) printf("%d\n", ans[i]); 99 } 100 return 0; 101 }