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 }
View Code

相关文章: