hdu 5072 Coprime(容斥+快速统计cnt个数与x互质的个数)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5072
题意:给n个数,从中选三个,三个数满足条件的要求是:三个数中两两互质或两两不互质,问满足条件的个数?

转换成求满足条件的反面:
①:a和b,c互质,b和c不互质
②:a和b,c不互质,b和c互质
于是就是枚举每个数,找出与他互质的个数与不互质的个数
答案就是:互质个数*不互质个数/2
至于为什么要除2,我看得还不是很懂

然后就变成了:怎样快速统计cnt个数与x互质的个数?
以前看过m以内与x互质的个数,也是容斥来求,但是那是m以内的每个数,而现在是随便cnt个数,这cnt个数长什么样子都不知道,怎么办呢?

我们看这个数与其他数互不互质就是看这个数与其他数有没有公共的质因子,如果有,那就不互质,于是就筛出这n个数中含有某个因子 i 的个数,用cnt2[i] 来表示
那么看某个数着n个数中的某个数 x 与他不互质的个数就是:
有一个公共质因子的个数 - 有两个公共质因子的个数+有三个公共质因子的个数…

其实感觉跟质因子有关的容斥,就跟莫比乌斯函数有关,上面的容斥系数就是莫比乌斯函数,所以阔以用莫比乌斯函数来直接求与这个数 x 互质的个数

①容斥做

#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
int cnt1[maxn];//记录i这个数有多少个
int cnt2[maxn];//看含有因子i 的数有多少个
vector<LL>factor[maxn];//用来保存这个数的质因子
vector<LL>prime;
int mu[maxn];
LL Max;
LL N;
bool vis[maxn];
void PHI(int n)
{
   
	memset(vis,1,sizeof(vis));
	mu[1]=1;
	for(int i=2; i<=n; i++)
	{
   
		if(vis[i])
		{
   
			prime.push_back(i);
			mu[i]=-1;
		}
		for(int j=0; j<prime.size()&&i*prime[j]<=n; j++)
		{
   
			vis[i*prime[j]]=0;
			if(i%prime[j]==0)
			{
   
				mu[i*prime[j]]=0;
				break;
			}
			else mu[i*prime[j]]=-mu[i];
		}
	}
}
void fenjie(LL n)//分解质因子
{
   
	if(factor[n].size())return ;
	LL t=0,m=n;
	while(n>1)
	{
   
		if(n%prime[t]==0)
		{
   
			factor[m].push_back(prime[t]);
			while(n%prime[t]==0)n/=prime[t];
		}
		if(prime[t]*prime[t]>n)break;
		t++;
	}
	if
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值