题干:

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

题目大意:

给出一棵树n个点,每个点上有权值。然后求每棵子树中与根节点互质,即gcd(a,b)=1的节点个数。

解题报告:

因为1e5以内的每个数的素因子个数不超过10个,所以可以对于每个数的不互素个数可以在O(10*2^10)内算出来,所以直接dfs序映射成一个序列然后按照题意求就行了。注意题目问的是gcd==1而不是互素,所以1和本身也是gcd==1的,所以val==1的时候需要ans++。

贴一个题解:

该题涉及到一个典型问题.问x与数的集合S中有多少个数不互素。解决办法是将S中所有元素依次进行两个步骤:①将元素进行质因数分解。②将质因数可能产生的乘积的出现次数加1。最后将x进行质因数分解,利用容斥原理求解。具体方案见代码。

容斥原理在OJ中常解决两个典型问题:①求S中有多少个数与x不互素。②求1~m中有多少个数与n不互素。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
vector<int> vv[MAX];
int val[MAX],ans[MAX],num[MAX];
int dfn[MAX],in[MAX],out[MAX],id;
vector<int> fac[MAX];
void db() {for(int tar = 1; tar<MAX; tar++) {int x = tar;for(int i = 2; i*i<=x; i++) {if(x%i == 0) {fac[tar].pb(i);while(x%i==0) x/=i;}}if(x > 1) fac[tar].pb(x);}
}
int cal(int n,int tar) {int res = 0;int upp = 1<<fac[n].size(),up = fac[n].size();for(int bit = 1; bit<upp; bit++) {int cnt = 0,mul = 1;for(int i = 0; i<up; i++) {if(bit & (1<<i)) {cnt++;mul *= fac[n][i];} }if(cnt & 1) res += num[mul];else res -= num[mul];num[mul] += tar;}return res;
}
int dfs(int cur,int rt) {int ans1 = cal(val[cur],0);int res = 0;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == rt) continue;res += dfs(v,cur);}int ans2 = cal(val[cur],1);ans[cur] = res - (ans2 - ans1);if(val[cur] == 1) ans[cur]++;return res+1;
}
int main()
{db();int n,iCase=0;while(~scanf("%d",&n)) {//initid=0;for(int i = 1; i<MAX; i++) num[i] = 0;for(int i = 1; i<=n; i++) vv[i].clear(),ans[i]=0;for(int a,b,i = 1; i<=n-1; i++) {scanf("%d%d",&a,&b);vv[a].pb(b);vv[b].pb(a);} for(int i = 1; i<=n; i++) scanf("%d",val+i);dfs(1,-1);printf("Case #%d:",++iCase);for(int i = 1; i<=n; i++) printf(" %d",ans[i]); printf("\n");   } return 0 ;
}

【HDU - 5468】Puzzled Elena(容斥原理,dfs序,数学,素因子分解,有坑)相关推荐

  1. hdu 5468 Puzzled Elena(前缀性质+dfs序+容斥)

    题目链接:hdu 5468 Puzzled Elena 解题思路 预处理出每个数的因子(注意只需要质因子幂数最大为1的数,例如6=21∗316=2^1 * 3^1)然后用一个数组维护,fac[i]表示 ...

  2. hdu 5468 Puzzled Elena

    一颗大小为(n<=100000) 的树,根为1,每个节点有个权值.问:每个节点 和 以这个节点为根的子树中 有多少权值和根的权值互质. 做法,我们首先要明白一个东西,就是当你已经知道了k个数,并 ...

  3. HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)

    题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...

  4. HDU - 5468 Puzzled Elena —— 容斥

    题意: 每个点的子树上有几个节点与该节点的权值互质 思路: 首先要明白怎么求一个集合中有多少个数与n互素 将集合中的数用算术基本定理分解,记录每个数能形成的所有因子的个数,然后将n分解进行容斥,可以求 ...

  5. HDU - 5468 Puzzled Elena (容斥/莫比乌斯)

    做了好几个容斥了,一直找不到feel,这个做完在现在有一点感觉了.虽然刚开始也不会.但就是发现感觉不一样了. 首先,不考虑树的关系,单纯给出一个m,还有一个集合(里面数字任意),求集合里面跟m互质的数 ...

  6. HDU 5468 Puzzled Elena 莫比乌斯反演

    题意: 给出一棵树,每个点上有权值.然后求每棵子树中与根节点互质( \(gcd(a, b) = 1\) )的节点个数. 分析: 对于一颗子树来说,设根节点的权值为\(u\), \(count_i\)表 ...

  7. 【HDU】5468 Puzzled Elena

    Puzzled Elena 题目链接 Puzzled Elena 题目大意 给你一棵树,n个节点n-1条边,每个节点都有一个权值.现在让你求每个节点的子树下面有多少个节点与该节点互质. 题解 容斥原理 ...

  8. HDU - 5877 Weak Pair (dfs序+树状数组+离散化)

    VJ地址 题意:给一个有根树给你,计算一下满足下列条件的序列对的数目 (1)u是v的祖先(不能是它自己) (2)a[v]*a[u]<=k 思路:用DFS序分裂每一条链,使链上的点都是当前加入点的 ...

  9. HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)

    描述 There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...

  10. hdu5468 Puzzled Elena(容斥原理+dfs序)

    hdu5468 题目 给一棵树,每个结点有一个值,现在求以每个结点为根的子树中与其互质的结点的个数 思路 这位博主讲的很好http://www.cnblogs.com/program-ccc/p/58 ...

最新文章

  1. 让div margin属性消失_margin 和 padding
  2. 如何停止一个正在运行的线程?
  3. c#中使用消息循环机制发送接收字符串的方法和数据类型转换
  4. pta龟兔赛跑Java_PTA-龟兔赛跑
  5. 【转】URL编码(encodeURIComponent和decodeURIComponent)
  6. sencha app watch php,我的第一个基于SenchaTouch的WebApp
  7. 基于JAVA+SpringBoot+Mybatis+MYSQL的小区物业管理系统
  8. Visual Studio 2017
  9. MakeGenericMethod Reflection 反射 ObjectToXmlT Generic XmlSerializer
  10. andorid 录音去噪音
  11. 木疙瘩离线版导出html,木疙瘩的功能介绍和特色
  12. Android DataStore 使用详解
  13. Java发送邮件,优美html邮件模板分享
  14. java计算机毕业设计楼宇管理系统源码+数据库+lw文档+系统
  15. 【模板】高精度取余函数
  16. 使用 javaScript 编写倒计时小程序,到时提交表单
  17. 实时系统与分时系统的区别
  18. Java实现积分过期保证时间_商城会员积分过期的实现方案
  19. 1-1HTML笔记总结
  20. Java判断手机号格式

热门文章

  1. [Leetcode][第486题][JAVA][预测赢家][动态规划][递归]
  2. [Leedcode][JAVA][第460题][LFU]
  3. 高仿人人android梦想版终极源码发送,人人Android客户端梦想版发布
  4. springboot接收json参数_Springboot + Vue + shiro 实现前后端分离、权限控制
  5. 装B指南之使用浏览器播放电影
  6. php获取悉尼时间,php在使用澳大利亚/悉尼时区时给出错误答案
  7. python 可视化监控平台_python可视化篇之流式数据监控的实现
  8. installshield 指定多个自定义路径和文件
  9. gsoap使用心得! (win32)
  10. WINCE6.0 DM.EXE 激活驱动失败的原因之一