Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very interesting tree rooted at vertex 1. There is an integer number written on each vertex of the tree; the number written on vertex i is equal to ai.
Ilya believes that the beauty of the vertex x is the greatest common divisor of all numbers written on the vertices on the path from the root to x, including this vertex itself. In addition, Ilya can change the number in one arbitrary vertex to 0 or leave all vertices unchanged. Now for each vertex Ilya wants to know the maximum possible beauty it can have.
For each vertex the answer must be considered independently.
The beauty of the root equals to number written on it.
Input
First line contains one integer number n — the number of vertices in tree (1 ≤ n ≤ 2·105).
Next line contains n integer numbers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 2·105).
Each of next n - 1 lines contains two integer numbers x and y (1 ≤ x, y ≤ n, x ≠ y), which means that there is an edge (x, y) in the tree.
Output
Output n numbers separated by spaces, where i-th number equals to maximum possible beauty of vertex i.
Example
Input
2
6 2
1 2
Output
6 6
Input
3
6 2 3
1 2
1 3
Output
6 6 6
Input
1
10
Output
10
求每个点到根的可去掉一个点的最大的gcd
第一种做法:把所有的前面所有的gcd都保存下来(就是每个点不要的的情况,用set保存下来)传参方面,传一个新的set,复杂度 n*logmax(a[i])(比这个小)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int a[N];
int an[N];
vector<int> e[N];
void dfs(int x,int y,int gg,set<int> s)
{
set<int> tt;
if(!x)
{
an[x]=a[x];
tt.insert(0);
}
else
{
an[x]=gg;
for(set<int>::iterator iter=s.begin();iter!=s.end();iter++)
{
tt.insert(__gcd(*iter,a[x]));
}
tt.insert(gg);
gg=__gcd(gg,a[x]);
an[x]=gg;
an[x]=max(an[x],*(--tt.end()));
}
for(int i=0;i<(int)e[x].size();i++)
{
if(e[x][i]==y) continue;
dfs(e[x][i],x,gg,tt);
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
set<int> ss;
dfs(1,0,0,ss);
for(int i=1;i<=n;i++)
printf("%d ",an[i] );
}
第二种做法,一开始也是想到分解因素,卡壳了,没想到分解因子再回溯,晚上脑子果然不好使 复杂度 On*2sqrt(a[i])
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int a[N];
vector<int> e[N];
int v[N];
int an[N];
void dfs(int x,int y,int d,int g)
{
int tt=0;
for(int i=1;i*i<=a[x];i++)
{
if(a[x]%i==0)
{
if(i*i==a[x])
{
v[i]++;
if(v[i]>=d)
tt=max(tt,i);
}
else
{
v[i]++;
v[a[x]/i]++;
if(v[i]>=d) tt=max(tt,i);
if(v[a[x]/i]>=d) tt=max(tt,a[x]/i);
}
}
}
tt=max(g,tt);
g=__gcd(g,a[x]);
an[x]=tt;
for(int i=0;i<e[x].size();i++)
{
if(e[x][i]==y) continue;
dfs(e[x][i],x,d+1,g);
}
for(int i=1;i*i<=a[x];i++)
{
if(a[x]%i==0)
{
if(i*i==a[x]) v[i]--;
else
{
v[i]--;
v[a[x]/i]--;
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0,0,0);
for(int i=1;i<=n;i++)
printf("%d ",an[i] );
return 0;
}