Puzzled Elena
Time Limit: 2500ms
Memory Limit: 131072KB
This problem will be judged on HDU. Original ID: 5468
64-bit integer IO format: %I64d Java class name: Main
Since both Stefan and Damon fell in love with Elena, and it was really difficult for her to choose. Bonnie, her best friend, suggested her to throw a question to them, and she would choose the one who can solve it.
Suppose there is a tree with n vertices and n - 1 edges, and there is a value at each vertex. The root is vertex 1. Then for each vertex, could you tell me how many vertices of its subtree can be said to be co-prime with itself?
NOTES: Two vertices are said to be co-prime if their values‘ GCD (greatest common divisor) equals 1.
Input
There are multiply tests (no more than 8).
For each test, the first line has a number n $(1\leq n\leq 10^5)$, after that has n−1 lines, each line has two numbers a and b$ (1\leq a,b\leq n)$, representing that vertex a is connect with vertex b. Then the next line has n numbers, the ith number indicates the value of the ith vertex. Values of vertices are not less than 1 and not more than $10^5$.
Output
For each test, at first, please output "Case #k: ", k is the number of test. Then, please output one line with n numbers (separated by spaces), representing the answer of each vertex.
Sample Input
5 1 2 1 3 2 4 2 5 6 2 3 4 5
Sample Output
Case #1: 1 1 0 0 0
Source
2015 ACM/ICPC Asia Regional Shanghai Online
解题:莫比乌斯反演
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 100010; 4 bool np[maxn] = {true,true}; 5 int mu[maxn],p[maxn],tot; 6 vector<int>fac[maxn],g[maxn]; 7 void mobius(int n) { 8 mu[1] = 1; 9 for(int i = 2; i <= n; ++i) { 10 if(!np[i]) { 11 p[tot++] = i; 12 mu[i] = -1; 13 } 14 for(int j = 0; j < tot && p[j]*i <= n; ++j) { 15 np[p[j]*i] = true; 16 if(i%p[j] == 0) { 17 mu[p[j]*i] = 0; 18 break; 19 } 20 mu[p[j]*i] = -mu[i]; 21 } 22 } 23 for(int i = 2; i <= n; ++i) if(mu[i]) 24 for(int j = i; j <= n; j += i) 25 fac[j].push_back(i); 26 } 27 int val[maxn],cnt[maxn],sz[maxn],ans[maxn]; 28 void dfs(int u,int fa) { 29 sz[u] = 1; 30 vector<int>pre; 31 for(int &c:fac[val[u]]) { 32 pre.push_back(cnt[c]); 33 ++cnt[c]; 34 } 35 for(auto &v:g[u]) { 36 if(v == fa) continue; 37 dfs(v,u); 38 sz[u] += sz[v]; 39 } 40 ans[u] = sz[u]; 41 for(int i = 0; i < fac[val[u]].size(); ++i) { 42 int x = fac[val[u]][i]; 43 int y = cnt[x] - pre[i]; 44 ans[u] += mu[x]*y; 45 } 46 } 47 int main() { 48 int n,u,v,cs = 1; 49 mobius(100000); 50 while(~scanf("%d",&n)) { 51 for(int i = 1; i <= n; ++i) g[i].clear(); 52 for(int i = 1; i < n; ++i) { 53 scanf("%d%d",&u,&v); 54 g[u].push_back(v); 55 g[v].push_back(u); 56 } 57 for(int i = 1; i <= n; ++i) 58 scanf("%d",val + i); 59 memset(cnt,0,sizeof cnt); 60 dfs(1,0); 61 printf("Case #%d:",cs++); 62 for(int i = 1; i <= n; ++i) 63 printf(" %d",ans[i]); 64 putchar(‘\n‘); 65 } 66 return 0; 67 }