086戴澎峰 - 数论入门.随堂练习.6 - 基因序列
public
May 13, 2025
Never
10
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 }