HDU - 5468 Puzzled Elena —— 容斥
题意:
每个点的子树上有几个节点与该节点的权值互质
思路:
首先要明白怎么求一个集合中有多少个数与n互素
将集合中的数用算术基本定理分解,记录每个数能形成的所有因子的个数,然后将n分解进行容斥,可以求出与n不互素的个数,总数减掉不互素的个数就是互素的数的个数
这个题也一样,只是把集合改成了树上的节点。
当我们dfs遍历树时,一定先访问父节点再访问子树,我们分别在访问父节点时和遍历完子树后再回到父节点时查询已经遍历过的树中所有与父节点权值不互质的个数,两者相减就是子树中与权值不互素的个数。
预处理出了1e5内所有数的因子
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 100010
#define mod 1000000007
#define inf 0x3f3f3f3f
bool vis[max_];
int prime[max_];
int pl=0;
void getprime()
{for(int i=2;i<max_;i++){if(vis[i]==false)prime[++pl]=i;for(int j=1;j<=pl&&prime[j]*i<max_;j++){vis[i*prime[j]]=true;if(i%prime[j]==0)break;}}
}
int casnum=1;
vector< vector<int> >v;
vector<int>num[100010];
int n;
int cnt[max_];
int val[max_];
int ans[max_];
void brk(int n)
{int tmp=n;for(int i=1;i<=pl&&prime[i]*prime[i]<=n;i++){if(n%prime[i]==0){num[tmp].push_back(prime[i]);while(n%prime[i]==0)n/=prime[i];}if(n==1)return;}if(n>1)num[tmp].push_back(n);
}
int cal(int w,int k)
{int ans=0;for(int i=1;i<(1<<num[w].size());i++){int sum=1;int cct=0;for(int j=0;j<num[w].size();j++){if(i&(1<<j)){cct++;sum*=num[w][j];}}if(cct&1)ans+=cnt[sum];elseans-=cnt[sum];cnt[sum]+=k;}return ans;
}
int dfs(int u,int fa)
{int pre=cal(val[u],0);int sum=0;for(int i=0;i<v[u].size();i++){if(v[u][i]!=fa){sum+=dfs(v[u][i],u);}}int eend=cal(val[u],1);ans[u]=sum-(eend-pre);if(val[u]==1)ans[u]++;return sum+1;
}
int main(int argc, char const *argv[]) {getprime();for(int i=1;i<=100000;i++)brk(i);while(scanf("%d",&n)!=EOF){v.clear();v.resize(n+1);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);v[x].push_back(y);v[y].push_back(x);}for(int i=1;i<=n;i++)scanf("%d",&val[i]);dfs(1,-1);printf("Case #%d:",casnum++);for(int i=1;i<=n;i++)printf(" %d",ans[i]);printf("\n");}return 0;
}
HDU - 5468 Puzzled Elena —— 容斥相关推荐
- hdu 5468 Puzzled Elena(前缀性质+dfs序+容斥)
题目链接:hdu 5468 Puzzled Elena 解题思路 预处理出每个数的因子(注意只需要质因子幂数最大为1的数,例如6=21∗316=2^1 * 3^1)然后用一个数组维护,fac[i]表示 ...
- HDU - 5468 Puzzled Elena (容斥/莫比乌斯)
做了好几个容斥了,一直找不到feel,这个做完在现在有一点感觉了.虽然刚开始也不会.但就是发现感觉不一样了. 首先,不考虑树的关系,单纯给出一个m,还有一个集合(里面数字任意),求集合里面跟m互质的数 ...
- hdu5468 Puzzled Elena(容斥 莫比乌斯反演)
hdu5468 Puzzled Elena 题意 求一棵子树内与它互质的点个数 解法 容斥 我们先求出与它不互质的数的个数,再用总数减去就好. #include <cstdio> #inc ...
- hdu 5468 Puzzled Elena
一颗大小为(n<=100000) 的树,根为1,每个节点有个权值.问:每个节点 和 以这个节点为根的子树中 有多少权值和根的权值互质. 做法,我们首先要明白一个东西,就是当你已经知道了k个数,并 ...
- HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)
题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...
- HDU 5468 Puzzled Elena 莫比乌斯反演
题意: 给出一棵树,每个点上有权值.然后求每棵子树中与根节点互质( \(gcd(a, b) = 1\) )的节点个数. 分析: 对于一颗子树来说,设根节点的权值为\(u\), \(count_i\)表 ...
- 【HDU】5468 Puzzled Elena
Puzzled Elena 题目链接 Puzzled Elena 题目大意 给你一棵树,n个节点n-1条边,每个节点都有一个权值.现在让你求每个节点的子树下面有多少个节点与该节点互质. 题解 容斥原理 ...
- 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)...
题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...
- HDU 4407 Sum(容斥+等差求和)
题目大意:给n个数,1-n.然后有m次操作,分别是求(x,y)中与p互质的和:将第x个数替换成c. 思路:一开始觉得区间操作往线段树上想,但是要存的东西太多,没有办法实现. 后面其实仔细一想跟前面几道 ...
最新文章
- 1123: 零起点学算法30——参加程序设计竞赛
- 机器人编程语言python-机器人行业,10大流行编程语言对比
- 找工作?该复习了!(转)
- 刚装了fedora 17,装机必备,解决视频格式和中文输入法。
- 怎样正确查看Linux的内存占用情况
- (三)比特币时间序列数据的AI异常检测
- Android的ArrayAdapter、SimpleAdapter、BaseAdapter与ListView的使用
- 分布式系统关注点——如何去实施「负载均衡」?
- 安装phpmyadmin
- 简单了解Java语言
- 按网络管理模式 计算机网络可分为,计算机网络应用 按网络管理模式分类
- 转帖 美国 工程索引 收录中国科技论文的最新规定
- VBlog项目代码理解之后端
- 倾斜摄影测量和游戏的未来
- u盘中病毒解决方法 (文件夹变成exe文件)
- 华师大 OJ 3036
- 我知道你在淘宝买过很多东西,但是你买过一所大学吗
- 计算机毕业设计ssm筋斗租车系统d0733系统+程序+源码+lw+远程部署
- java 省市联动_Java 地区字典之省市区三级联动 (一)
- 探索性数据分析EDA(二)—— 缺失值处理