1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue" using namespace std; #define MAXN 200006
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll; ll n , m; int A[MAXN]; int gcd( int a , int b ) { return !b ? a : gcd( b , a % b ); } vector<int> divs[MAXN]; int pri[MAXN] , en; void prewk( ) { for( int i = 2 ; i < MAXN ; ++ i ) { if( !pri[i] ) pri[++ en] = i; for( int j = 1 ; j <= en && i * pri[j] < MAXN ; ++ j ) { pri[i * pri[j]] = 1; if( i % pri[j] == 0 ) break; } } for( int i = 1 ; i < MAXN ; ++ i ) for( int j = i ; j < MAXN ; j += i ) divs[j].pb( i ); } vector<int> G[MAXN];
int vis[MAXN]; int siz[MAXN] , mx[MAXN] , S , pr; void fds( int u , int fa ) { siz[u] = 1; mx[u] = 0; for( int v : G[u] ) if( !vis[v] && v != fa ) fds( v , u ) , mx[u] = max( mx[u] , siz[v] ) , siz[u] += siz[v]; } void sdf( int u , int fa ) { mx[u] = max( mx[u] , S - siz[u] ); if( mx[u] < mx[pr] ) pr = u; for( int v : G[u] ) if( !vis[v] && v != fa ) sdf( v , u ); } int getit( int u ) { pr = u; fds( u , u ); S = siz[u]; sdf( u , u ); return pr; } int g[MAXN] , gg[MAXN] , ok[MAXN]; vector<int> pts , pall; void dfs( int u , int fa ) { pts.pb( u ); for( int v : G[u] ) if( !vis[v] && v != fa ) { g[v] = gcd( g[u] , A[v] ); dfs( v , u ); } } long long ans[MAXN]; void work( int u ) { vis[u] = 1; pall.clear(); for( int x : divs[A[u]] ) ++ ans[x] , ++ gg[x] , pall.pb( x ); for( int v : G[u] ) if( !vis[v] ) { pts.clear(); g[v] = gcd( A[u] , A[v] ) , dfs(v, u); for( int x : pts ) for( int p : divs[g[x]] ) ans[p] += gg[p]; for( int x : pts ) for( int p : divs[g[x]] ) ++ gg[p] , pall.pb( p ); } for( int t : pall ) gg[t] = 0; for( int v : G[u] ) if( !vis[v] ) work( getit( v ) ); } void solve() { prewk(); cin >> n; rep( i , 1 , n ) scanf("%d",A + i); int u , v; rep( i , 2 , n ) { scanf("%d%d",&u,&v); G[u].pb( v ) , G[v].pb( u ); } work( getit( 1 ) ); for( int i = en ; i ; -- i ) for (int j = 1; j * pri[i] < MAXN; ++j) ans[j] -= ans[j * pri[i]]; for( int i = 1 ; i < MAXN ; ++ i ) if( ans[i] ) printf("%d %lld\n",i,ans[i]); }
signed main() {
solve(); }
|