Description
In this paper, we give a root tree of nn nodes, the root node is 11, each point has a bit of weight VI VI, the contribution of two different points i,ji,j to its lcalcalca score is gcd(vi,vj)gcd(vi,vj), the initial score of each point is − 1 − 1, the final score of one point is the maximum value of all the contribution scores, and ask the final score of each point
Input
In the first line, an integer n n represents the number of points, then input n − 1n − 1 integer f2,...,fnf2,...,fn to represent the parent node of each point, and finally input nn integer vivi to represent the weight of each point
(1≤n≤105,fi<i,vi≤105)(1≤n≤105,fi<i,vi≤105)
Output
Output the final score of each point
Sample Input
4
1 1 3
4 1 6 9
Sample Output
2
-1
3
-1
Solution
Enumerate dd from small to large, count the points whose ownership value is the multiple of dd. after sorting these points in the order of dfsdfs, the set of lcalcas of any two points in these points is the same as the set of lcalcalcas of adjacent two points. Then we get the lcalcalcas of adjacent two points, and use dd to update the scores of these lcalcalcalcas. Since only O(nlogn)O(nlogn) times LCALCA are calculated at most, the total time complexity is O (NLog 2n) O (nlog2n)
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define maxn 100005
int p[maxn][18],dep[maxn],dfn[maxn],index,ans[maxn];
vector<int>g[maxn],f[maxn];
void dfs(int u)
{
dfn[u]=++index;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
dep[v]=dep[u]+1;
dfs(v);
}
}
int lca(int a,int b)
{
int i,j;
if(dep[a]<dep[b])swap(a,b);
for(i=0;(1<<i)<=dep[a];i++);
i--;
for(j=i;j>=0;j--)
if(dep[a]-(1<<j)>=dep[b])
a=p[a][j];
if(a==b) return a;
for(j=i;j>=0;j--)
if(p[a][j]&&p[a][j]!=p[b][j])
{
a=p[a][j];
b=p[b][j];
}
return p[a][0];
}
int cmp(int x,int y)
{
return dfn[x]<dfn[y];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
scanf("%d",&p[i][0]);
g[p[i][0]].push_back(i);
}
dep[1]=0;
index=0;
dfs(1);
for(int j=1;j<18;j++)
for(int i=1;i<=n;i++)
p[i][j]=p[p[i][j-1]][j-1];
int m=0;
for(int i=1;i<=n;i++)
{
int w;
scanf("%d",&w);
m=max(m,w);
for(int j=1;j*j<=w;j++)
if(w%j==0)
{
f[j].push_back(i);
if(j*j!=w)f[w/j].push_back(i);
}
}
memset(ans,-1,sizeof(ans));
for(int i=1;i<=m;i++)sort(f[i].begin(),f[i].end(),cmp);
for(int i=1;i<=m;i++)
if(f[i].size()>1)
{
int pre=f[i][0];
for(int j=1;j<f[i].size();j++)
{
int t=lca(pre,f[i][j]);
ans[t]=i;
pre=f[i][j];
}
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}