時間限制:1秒
空間限制:32768K
輸入描述:
第1行:整數n(1 ≤ n ≤ 100000),表示點的個數。 第2~n行:每行兩個整數x,y表示xy之間有邊,數據保證給出的是一棵樹。 第n+1行:n個整數,依次表示點1~n對應的權值(1 ≤ 權值 ≤ 1,000,000,000)。
輸出描述:
滿足最長路徑的長度
輸入例子:
4 1 2 1 3 2 4 6 4 5 2
輸出例子:
3
1具體就是枚舉所以質因子,然後dfs的時候只走有當前這個質因子的點。。。這樣的話正面看來複雜度貌似很大,最多有10W個質因子,每次dfs複雜度上限也是10W,,貌似會超時? 這個時候要從另外一個角度計算複雜度啦。我們對一個數來考慮,他會被幾次dfs遍歷到?。很顯然就是它的質因子的數量次,,一個數的質因子數比logn還要小很多。所以所有數只會被遍歷到最多 nlogn次,複雜度也差不多nlogn級別的,就不會超時了
#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin)
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<"q"<<endl;
#define MX 111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
const double eps=1e-8;
int n;
int val[MX];
bool isprime[MX];
int prime[MX],prime_cnt;
void prime_init()
{
prime_cnt=0;
mem(isprime,1);
for(int i=2; i<MX; i++)
{
if(isprime[i])prime[prime_cnt++]=i;
for(int j=0; j<prime_cnt&&prime[j]*i<MX; j++)
{
isprime[prime[j]*i]=0;
if(i%prime[j]==0)break;
}
}
}
int head[MX],edge_cnt;
struct Edge
{
int nxt,to;
} E[MX*2];
void edge_init()
{
mem(head,-1);
edge_cnt=0;
}
void edge_add(int u,int v)
{
E[edge_cnt].nxt=head[u];
E[edge_cnt].to=v;
head[u]=edge_cnt++;
}
int vis[MX];
int num[MX];
map<int,vector<int> >mp;
int w;
int dfs(int u,int fa)
{
num[u]=1;
int MM=0,M=0;
int ans=0;
for(int i=head[u]; ~i; i=E[i].nxt)
{
int v=E[i].to;
if(v==fa||val[v]%w)continue;
ans=max(ans,dfs(v,u));
if(num[v]>MM)M=MM,MM=num[v];
else if(num[v]>M)M=num[v];
}
num[u]=M+MM+1;
return max(ans,num[u]);
}
int solve(int u)
{
w=u;
int ans=0;
for(auto i:mp[u])
{
if(vis[i]==0)ans=max(ans,dfs(i,-1));
}
for(auto i:mp[u])vis[i]=0;
return ans;
}
int main()
{
prime_init();
FIN;
while(cin>>n)
{
edge_init();
mp.clear();
for(int i=1; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
edge_add(u,v);
edge_add(v,u);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&val[i]);
int x=val[i];
for(int j=0; prime[j]<=sqrt(x+0.5); j++)
{
if(x%prime[j]==0)mp[prime[j]].push_back(i);
while(x%prime[j]==0)x/=prime[j];
}
if(x!=1)mp[x].push_back(i);
}
int ans=0;
for(auto i:mp)
{
ans=max(ans,solve(i.first));
}
cout<<ans<<endl;
}
return 0;
}