【数论】BZOJ 2818 Gcd

本文解析了一道数论题,通过枚举素数并利用欧拉函数计算互质数对数量,介绍了如何求解N内与任一数互质的数的对数。使用前缀和优化计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

这道题看起来是一道很水的数论题
实际上就是一道很水的数论题Σ( ° △ °

G c d ( x , y ) = p Gcd(x,y)=p Gcd(x,y)=p,则 G c d ( x / p , y / p ) = 1 Gcd(x/p,y/p)=1 Gcd(x/p,y/p)=1
所以我们枚举素数 p p p,求出 N / p N/p N/p以内的互质的数的对数,然后每一个 p p p之下的答案求和就是最终答案

而欧拉函数的意义就是这个数以内与它互质的数的个数,所以我们把 p h i [ 1 ] phi[1] phi[1] p h i [ N / p ] phi[N/p] phi[N/p]加起来就是 N / p N/p N/p以内的互质的数的对数,筛出来之后用个前缀和就可以了。

由于这个数对是有序的,每次我们*2再减1(1,1的情况)就可以了

另外学校OJ的要求高一些 所以把phi和前缀和数组合并到了一起,否则会MLE

#include<cstdio>
#define LL long long
#define MAXN 10000005
int n,pn,prime[MAXN];
bool vis[MAXN];
LL ans,phi[MAXN];
void sieve()
{
	phi[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i])
		{
			phi[i]=i-1;
			prime[++pn]=i;
		}
		for(int j=1;j<=pn&&i*prime[j]<=n;j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			else phi[i*prime[j]]=phi[i]*phi[prime[j]];
		}
	}
}
int main()
{
	scanf("%d",&n);
	sieve();
	for(int i=1;i<=n;i++)
		phi[i]=phi[i-1]+phi[i];
	for(int i=1;i<=pn;i++)
		ans+=phi[n/prime[i]]*2-1;
	printf("%lld\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值