码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5468 Puzzled Elena

时间:2015-10-24 11:23:06      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

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

 
解题:莫比乌斯反演
技术分享
 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 }
View Code

 

HDU 5468 Puzzled Elena

标签:

原文地址:http://www.cnblogs.com/crackpotisback/p/4906428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!