菜鸡学数论(一)

先确认一下入门数论的基本知识点:

  1. 最大公约数

  2. 快速幂

  3. 素数筛


辗转相除求最大公约数:

int gcd(int a,int b)
{
    if(b==0) return a;
    gcd(b,a%b);
}

素数筛的模板(线性筛):将2到n之间的整数记录下来,其中最小的素数是2,将表中2的倍数全部不划去,表中剩余的最小的数字为3,再将3的倍数全划去,以此类推,就能找到所有的素数。这样做的时间复杂度只有o(nlog log n)。

int prime[maxn];///用于标记晒是否已经筛过
int pri[maxn];///用于储存素数
void pre_prime()
{
    memset(prime,0,sizeof(prime));
    cnt = 0;
    prime[0] = prime[1] = 1;
    for(int i = 2 ; i < maxn  ; i++)
    {
        if(!prime[i]) pri[cnt++] = i;
        for(int j = 0 ; j < cnt && i * pri[j] <= maxn ; j++)
        {
            prime[i * pri[j]] = 1;
            if(i % pri[j] == 0) break;///已经筛过的不要重复筛
        }
    }
}

快速幂:数论问题经常遇见非常大的数,例如 X ^ 22,通常的思路是采用for循环,但当数很大时运算效率会很低。

采用快速幂算法可以将X22拆为X16 , X4和X2。时间复杂度直降至o(log n)。

    typedef long long ll;
    ll quick_pow(ll x,ll n,ll mod)
    {
        ll ans=1;
        while(n>0)
        {
            if(n&1) 
                ans=ans*x%mod;
            x=x*x%mod;
            n>>=1;
        }
        return ans;
    }

敲黑板:n&1的作用是判断最后一位是否是1,是一的话就是要单乘一次再翻倍(因为有右移n>>1),不是一的话直接翻倍.


欧拉函数
欧拉函数是少于或等于n的数中与n互质的数的数目。
欧拉函数的性质:它在整数n上的值等于对n进行素因子分解后,所有的素数幂上的欧拉函数之积。
欧拉函数的值  通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)……(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数(小于等 于1)就是1本身)。 (注意:每种质因数只一个。比如12=223,那φ(12)=12*(1-1/2)*(1-1/3)=4)
推论:当n为奇数时,有φ(2n)=φ(n)。
若n是质数p的k次幂,φ(n)=pk-p(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。
设n为正整数,以 φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值,这里函数φ:N→N,n→φ(n)称为欧拉函数。
欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。
特殊性质:当n为奇数时,φ(2n)=φ(n), 证明与上述类似。
那么如果我们想要求出其欧拉函数的值就要先对n进行质因子分解:
如果进行直接进行筛因子的话其时间复杂度为O(n),代码如下

int prime(int n)
{
    int rea=n;
    for(int i=2; i<=n; i++)
        if(n%i==0)//第一次找到的必为素因子
        {
            rea=rea-rea/i;
            do
                n/=i;//把该素因子全部约掉
            while(n%i==0);//比如12=2*2*3这样可以将所有的2除去
        }
    return rea;
}

有没有方法将其降低复杂度呢?我们知道 “ 由于任何一个合数都至少有一个不大于根号n的素因子 ”,所以只需遍历到根号n即可

int prime(int n)
{
    int rea=n;
    for(int i=2; i*i<=n; i++)
        if(n%i==0)//第一次找到的必为素因子
        {
            rea=rea-rea/i;
            do
                n/=i;//把该素因子全部约掉
            while(n%i==0);
        }
    if(n>1)
        rea=rea-rea/n;//如果到最后n有就将n直接处理 
    return rea;
}

最后学长说用筛法求欧拉函数很好(可能我太菜了吧,,,,没有领会到)

primel prime[50000];
int pri[20000];
void prim()
{
    memset(prime,0,sizeof(prime));
    prime[0]=prime[1]=1;
    int k=0;
    for(int i=2; i<50000; i++)
    {
        if(!prime[i])
            pri [k++]=i;
        for(int j=0; j<k&&i*pri [j]<50000; j++)
        {
            prime[i*p[j]=1;
                if(!(i%pri [j]))
                break;
        }
}
}//筛选法打表
int phi(int n)
{
    int rea=n;
    for(int i=0; pri [i]*pri [i]<=n; i++)//对于一些不是素数的可不遍历
        if(n%pri [i]==0)
        {
            rea=rea-rea/n;
            do
                n/=pri [i];
            while(n%pri [i]==0);
        }
    if(n>1)
        rea=rea-rea/n;
    return rea;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值