G

086戴澎峰 - 数论入门.随堂练习.6 - 基因序列

public
Guest May 13, 2025 Never 10
Clone
C++ 086戴澎峰 - 数论入门.随堂练习.6 - 基因序列 83 lines (77 loc) | 2.02 KB
1
#include <bits/stdc++.h>
2
using namespace std;
3
#define LL long long
4
#define INF 0x3f3f3f3f
5
const int N = 2e6+5, M = 2e5+5;
6
vector<int>v[N];
7
struct Edge {
8
int v,nxt;
9
}e[M<<1];
10
int head[N],cnt;
11
void add(int u,int v) {
12
e[++cnt].v = v;
13
e[cnt].nxt = head[u];
14
head[u] = cnt;
15
}
16
int n, q;
17
//void Init() {
18
// for(int i=2;i<N;i++)
19
// for(int j=i;j<N;j+=i)
20
// v[j].push_back(i);
21
//}
22
list<int>st[N]; // 用 list 模拟栈
23
int ot[N], h[N], a[N];
24
25
void dfs(int u) {
26
int ans = -1, hmax = -1;
27
for(int i=1;i*i<=a[u];i++) { // 筛至平方根, 遍历 a[u] 的所有因子
28
if(a[u]%i) continue;
29
if(!st[i].empty() && h[st[i].back()] > hmax) { // 有 包含 因子 的祖先结点, 且 深度 大于 记录的最大深度
30
hmax = h[st[i].back()];
31
ans = st[i].back(); // 更新答案
32
}
33
if(i!=1) st[i].push_back(u); // 除了因子 1,都 将 u 放入 因子 对应的栈中
34
35
int w = a[u] / i; // 取 对称的因子, 对于 6, 2 和 3 对称, 1 和 6 对称
36
if(w==i) continue; // 平方根 ,不重复计算
37
38
if(!st[w].empty() && h[st[w].back()] > hmax) { // w 的处理, 与 i 同理
39
hmax = h[st[w].back()];
40
ans = st[w].back();
41
}
42
st[w].push_back(u);
43
}
44
45
ot[u] = ans; // 记录答案
46
for(int i=head[u];i;i=e[i].nxt) {
47
int v = e[i].v;
48
h[v] = h[u] + 1; // 更新 子节点 深度
49
dfs(v); // 遍历 子节点
50
}
51
52
// 退出时,还原
53
for(int i=1;i*i<=a[u];i++) {
54
if(a[u]%i) continue;
55
if(i!=1) st[i].pop_back(); // 放入的元素,退出
56
int w = a[u] / i;
57
if(w==i) continue;
58
st[w].pop_back();
59
}
60
}
61
void solve() {
62
cin >> n >> q;
63
// Init();
64
for(int i=1;i<=n;i++)
65
cin >> a[i];
66
for(int i=1;i<n;i++) {
67
int u, v;
68
cin >> u >> v;
69
add(u,v);
70
}
71
dfs(1);
72
for(int _=0;_<q;_++) {
73
int a;
74
cin >> a;
75
cout << ot[a] << "\n";
76
}
77
}
78
79
int main() {
80
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
81
solve();
82
return 0;
83
}