您的位置:首页 > 其它

HDU 5468 Puzzled Elena

2015-10-24 11:08 225 查看

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

解题:莫比乌斯反演

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
bool np[maxn] = {true,true};
int mu[maxn],p[maxn],tot;
vector<int>fac[maxn],g[maxn];
void mobius(int n) {
mu[1] = 1;
for(int i = 2; i <= n; ++i) {
if(!np[i]) {
p[tot++] = i;
mu[i] = -1;
}
for(int j = 0; j < tot && p[j]*i <= n; ++j) {
np[p[j]*i] = true;
if(i%p[j] == 0) {
mu[p[j]*i] = 0;
break;
}
mu[p[j]*i] = -mu[i];
}
}
for(int i = 2; i <= n; ++i) if(mu[i])
for(int j = i; j <= n; j += i)
fac[j].push_back(i);
}
int val[maxn],cnt[maxn],sz[maxn],ans[maxn];
void dfs(int u,int fa) {
sz[u] = 1;
vector<int>pre;
for(int &c:fac[val[u]]) {
pre.push_back(cnt[c]);
++cnt[c];
}
for(auto &v:g[u]) {
if(v == fa) continue;
dfs(v,u);
sz[u] += sz[v];
}
ans[u] = sz[u];
for(int i = 0; i < fac[val[u]].size(); ++i) {
int x = fac[val[u]][i];
int y = cnt[x] - pre[i];
ans[u] += mu[x]*y;
}
}
int main() {
int n,u,v,cs = 1;
mobius(100000);
while(~scanf("%d",&n)) {
for(int i = 1; i <= n; ++i) g[i].clear();
for(int i = 1; i < n; ++i) {
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i = 1; i <= n; ++i)
scanf("%d",val + i);
memset(cnt,0,sizeof cnt);
dfs(1,0);
printf("Case #%d:",cs++);
for(int i = 1; i <= n; ++i)
printf(" %d",ans[i]);
putchar('\n');
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: