Puzzled Elena

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1247    Accepted Submission(s): 370

Problem Description
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≤n≤105), after that has n−1 lines, each line has two numbers a and b (1≤a,b≤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 105.
 
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
 
题意:给定 n 个结点 n-1条边的一棵树 ,每个结点都有一个 value,问每个节点的子节点的value与其value互素的个数有多少?
题解:我们可以先预处理出 1 ~ 10^5 内所有整数的因子,然后进行 DFS,当进入结点 u 时,记录当前与 u 不互素的数的个数为 a ,出节点 u 时,记录这时与 u不互素的个数为b,那么 u 的子树中 与 value[u] 不互素的个数就为 b-a ,当前结点 u 的子节点结点个数为 s,那么与 其互素的数个数为 s - (b-a).这里用一个 cnt[i]数组记录当前含有因数 i 的结点的个数,每次退出结点 u 的时候要将含有其因子的数量累加.还有就是当 val[u] == 1时,他与本身互素,答案 +1 .
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = ;
vector <int> factor[N];
vector <int> edge[N];
void init(){
for(int i=;i<N;i++){
factor[i].clear();
int n = i;
for(int j=;j*j<=n;j++){
if(n%j==){
factor[i].push_back(j);
while(n%j==) n/=j;
}
}
if(n>) factor[i].push_back(n);
}
}
int cnt[N]; ///cnt[i]表示遍历到当前结点时候,含有因数i的结点个数。
int val[N];
int ans[N];
int solve(int n,int val){
int len = factor[n].size(),ans=;
for(int i=;i<(<<len);i++){
int odd = ;
int mul = ;
for(int j=;j<len;j++){
if((i>>j)&){
odd++;
mul*=factor[n][j];
}
}
if(odd&){
ans+=cnt[mul];
}
else ans-=cnt[mul];
cnt[mul]+=val; /// val = 1 代表退出当前结点时把因子加上
}
return ans;
}
int dfs(int u,int pre){
int L = solve(val[u],); ///第一次遍历到 u,拥有与 u 相同的因子个数
int s = ; ///s 代表当前结点下的子节点数目
for(int i=;i<edge[u].size();i++){
int v = edge[u][i];
if(v==pre) continue;
s+=dfs(v,u);
}
int R = solve(val[u],);
ans[u] = s - (R-L);
if(val[u]==) ans[u]++;
return s+;
}
int main()
{
init();
int n,t = ;
while(scanf("%d",&n)!=EOF){
memset(cnt,,sizeof(cnt));
for(int i=;i<=n;i++) edge[i].clear();
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
}
dfs(,-);
bool flag = true;
printf("Case #%d: ",t++);
for(int i=;i<=n;i++){
if(!flag) printf(" ");
flag = false;
printf("%d",ans[i]);
}
printf("\n");
}
return ;
}

hdu 5468(dfs序+容斥原理)的更多相关文章

  1. HDU 3966 dfs序+LCA+树状数组

    题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...

  2. HDU 5877 [dfs序][线段树][序]

    /* 题意: n个点的树,每个点给定一个权值,给定一个k,求任意一点的子树中,权值小于k/该点权值的点共有多少个. 思路: 1.很明显的子树的操作,应用dfs序. 2.比赛的时候傻逼了,一直在调划分树 ...

  3. hdu 5692(dfs序+线段树,好题)

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  4. HDU5468(dfs序+容斥原理)

    Puzzled Elena Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  5. HDU 5692 (DFS序+线段树)

    DFS获得从0到每一个顶点的距离,同时获得L和R数组.两数组为遍历时从i进入再从i出来的序列. #pragma comment(linker, "/STACK:1024000000,1024 ...

  6. Assign the task HDU - 3974 (dfs序 + 线段树)

    有一家公司有N个员工(从1到N),公司里每个员工都有一个直接的老板(除了整个公司的领导).如果你是某人的直接老板,那个人就是你的下属,他的所有下属也都是你的下属.如果你是没有人的老板,那么你就没有下属 ...

  7. dfs序题目练习

    参考博文:http://blog.csdn.net/qwe2434127/article/details/49819975 http://blog.csdn.net/qq_24489717/artic ...

  8. HDU 4358 Boring counting(莫队+DFS序+离散化)

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) ...

  9. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

随机推荐

  1. 修改apache的注册表值提高系统权限

    In Windows environments when a service is registered with the system a new key is created in the reg ...

  2. POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)

    POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...

  3. Codeforces 906B. Seating of Students(构造+DFS)

    行和列>4的可以直接构造,只要交叉着放就好了,比如1 3 5 2 4和2 4 1 3 5,每一行和下一行用不同的方法就能保证没有邻居. 其他的可以用爆搜,每次暴力和后面的一个编号交换并判断可行性 ...

  4. selenium - switch_to_alert() - 警告框处理

    在WebDriver中处理JavaScript所生成的alert.confirm以及prompt十分简单,具体做法是使用 switch_to.alert 方法定位到 alert/confirm/pro ...

  5. 编写优质嵌入式C程序(转)

    前言:这是一年前我为公司内部写的一个文档,旨在向年轻的嵌入式软件工程师们介绍如何在裸机环境下编写优质嵌入式C程序.感觉是有一定的参考价值,所以拿出来分享,抛砖引玉. 转载请注明出处:http://bl ...

  6. Codeforces 25.E Test

    E. Test time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  7. bzoj1467 Pku3243 clever Y

    1467: Pku3243 clever Y Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 313  Solved: 181[Submit][Status ...

  8. BNU-2017.7.4排位赛2总结

    链接:https://www.bnuoj.com/v3/contest_show.php?cid=9147#info A题 sort之后交换首尾两个数. B题 for一遍,如果每个数都在对应位置了,输 ...

  9. java rmi远程方法调用实例

    RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外一台计 ...

  10. [转]hadoop2.x常用端口

    原文地址:http://www.zhixing123.cn/ubuntu/40649.html HDFS DataNode 50010 dfs.datanode.address datanode服务端 ...