hdu 1787 欧拉函数算法

本文介绍了一种利用欧拉函数计算指定范围内与给定整数n不互素的整数个数的方法。通过解析n的素因数分解,并运用包含排斥原理,推导出计算公式。

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

题目大意:

输入一个整数n,让你求出0~n之间(不包括0和n)和n的公约数大于1(即不互素)的数的个数;

基本思路:

欧拉函数求出互素的数的个数,然后总共n-1个数减去互素的个数,得到答案;

补充:
欧拉函数:
给定正整数n,根据唯一分解定理,然后就会有n的素因数分解式

n=p1^a1*p2^a2*...*pk^ak为n的素因子分解式,

令Ai={x|0<=x<n-1且pi整除x}  (pi整出x,pi整出n,所以x和pi不互素,所以下面用AI的补集来计算)

那么(欧拉函数这个符号我就不打了,好麻烦的吧,就用w代替了,补集就用前面加一个-代替,交集就用&代替了)

w(n)=|-A1&-A2&...&-AK|;

那么|A1|=n/pi,i=1,2,...,k; |Ai&Aj|=n/(pi*pj);1<=i<=j<=n; (n/pi这一个计算要想清楚,因为没有n又添了0,所以数值上相等)

然后用包含排斥原理得到答案,

w(n)=|A1&A2&...&AK|=n-(n/p1+n/p2+...+n/pk)+(....)-(...)+(-1)^kn/(p1p2...pk)=n(1-i/p1)(1-1/p2)(1-1/p3)...(1/1/pk);

推导完毕;


代码如下:

注意1的时候的特殊情况;

#include<bits/stdc++.h>


int Euler(int n)
{
    int res=n;
    int m=sqrt(n);
    for(int i=2;i<=m;i++)
    {
        if(!(n%i))
            res=res/i*(i-1);
        while(!(n%i))
            n/=i;
    }
    if(n>1) res=res/n*(n-1);//这里就算剩下也只能剩下一个素数,因为sqrt所以只能剩下一个,然后必然是个素数,因为如果不是素数,前面肯定已经约了;
    return res;
}
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        if(!n) break;
        int sum=n-1;
        int res=Euler(n);
        printf("%d\n",res);
        if(n!=1)
        printf("%d\n",sum-res);
        else
        printf("0\n");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值