zoukankan      html  css  js  c++  java
  • 数论基础学习总结(持续补充中)

    数论基础

    算术基本定理(唯一分解定理)

    任何一个大于1的自然数都可以唯一分解成有限个素数的乘积

    $N=p_1^{a_1} imes p_2^{a_2} imes... imes p_n^{a_n} | p_1<p_2<...<p_n ,a_iin Z$

    上式中$p_i$为素数

    有关素数筛

    埃式筛法

    就是拿一个已经筛选出的素数去排掉其他的数,比如2是素数,就用他筛掉2*2,2*3,2*4……,3是素数,就用他筛掉3*2,3*3,3*4……,把每个素数的倍数都筛掉,不过我们发现,3*2事实上已经在2的时候筛掉过了,即比这个数小的倍数都已经被筛过了,所以我们只要从这个数的平方开始筛就可以了。这个筛法最容易理解也最好写,一定要会写!经过这个筛法,能打素数表,能判定一个数是不是素数。复杂度O(nloglogn)。也可以用这种筛法筛出因子。

     1 const int N=1e6+7;
     2 bool isprime[N];
     3 int prime[N];//储存素数,打表
     4 void db()
     5 {
     6     memset(isprime,1,sizeof(isprime));//这步事实上不太好,不过因为是bool类型所以不影响结果
     7     isprime[0]=isprime[1]=0;
     8     int cntp=0;
     9     for(long long i=2;i<N;i++)
    10     {
    11         if(isprime[i])
    12         {
    13             prime[cntp++]=i;
    14             for(long long j=i*i;j<N;j+=i)//i*i会爆int所以用ll
    15                 isprime[j]=0;
    16         }
    17     }
    18 }
    埃式筛法

    欧拉线性筛法

    正常情况下就算是没有优化的埃式筛法应该也是够用的,但是我们发现埃式筛法还是不是最快的,比如12这个数会被2和3筛两次,诸如此类的重复会降低效率。所以我们给出欧拉线性筛法。这个筛法自然比较难理解一点,其思路是这样的,从2开始,将这个素数和之前筛出的所有素数的乘积都判负,如果碰到i是一个合数,也用他去筛,但在筛的循环中碰到一个是他因子的素数就跳出(一个合数必定能表示成至少一个素数参与的分解式),达到避免重复筛的目的,然后一个循环后就筛出了素数。这个方法比较难理解,我也不是很能感受到这个方法的正确性,不过据说用反证法能进行证明。复杂度O(n)。

    线性筛还能用在处理其他积性函数上。

     1 const int N=1e6+7;
     2 bool isprime[N];
     3 int prime[N];
     4 void db()
     5 {
     6     memset(isprime,1,sizeof(isprime));
     7     isprime[0]=isprime[1]=0;
     8     int cntp=0;
     9     for(int i=2;i<N;i++)
    10     {
    11         if(isprime[i])
    12             prime[cntp++]=i;
    13     //这一部分是精髓所在也是难理解的部分,不管i是否是素数,都进循环去筛,i是合数时中途会跳出,达到减少重复筛的目的
    14         for(int j=0;j<cntp&&i*prime[j]<N;j++)
    15         {
    16             isprime[i*prime[j]]=0;
    17             if(!(i%prime[j]))
    18                 break;
    19         }
    20     }
    21 }
    欧拉线性筛

     有关因子

    求因子个数

    前置定理:若p是一个素数,a是一个正整数,那么有$ au(p^a)=a+1$。

    定理:若正整数n有质因数分解$n=p_1^{a_1} imes p_2^{a_2} imes... imes p_k^{a_k}$,则$ au(n)=(a_1+1) imes(a_2+1) imes... imes(a_k+1)$。

    我们需要先打出一张素数表才能套用这个。

     1 int factor_count(int n)
     2 {
     3     int ans=1;
     4     int cnt;
     5     int k=sqrt(n)+1;
     6     for(int i=0;prime[i]<k;i++)
     7     {
     8         if(n%prime[i]==0)
     9         {
    10             cnt=0;
    11             while(n%prime[i]==0)
    12             {
    13                 cnt++;
    14                 n/=prime[i];
    15             }
    16             ans*=(cnt+1);
    17         }
    18     }
    19     if(n>1)//这一步是因为只筛到根号n,可能会留最后一个因子,此时需要再算上这个因子
    20         ans*=2;
    21     return ans;
    22 }
    求因子个数

     素因子筛

    利用埃式筛法处理,复杂度O(nloglogn)

     1 const int maxn=1e5+7;
     2 void db()
     3 {
     4     vector<int> d[maxn];
     5     for(int i=2;i<maxn;i++)
     6         if(d[i].empty())
     7         {
     8             for(int j=2*i;j<maxn;j+=i)
     9                 d[j].push_back(i);
    10         }
    11 }
    素因子筛

    有关GCD

    辗转相除法

    1 long long gcd(long long a,long long b)
    2 {
    3     return b?gcd(b,a%b):a;
    4 }
    GCD

    扩展欧几里得

     1 long long exgcd(long long a,long long b,long long &x,long long &y)
     2 {
     3     if(b==0)
     4     {
     5         x=1,y=0;
     6         return a;
     7     }
     8     long long gcd=exgcd(b,a%b,y,x);
     9     y-=a/b*x;
    10     return gcd;
    11 }
    exgcd

     欧拉定理

    费马小定理

    设p是质数,a是与p互质的任意整数,那么有:$a^{p-1}equiv1(mod p)$

    欧拉定理

    设m>1为整数,a是与m互质的任意整数,那么有:$a^{varphi(m)equiv1(mod m)}$

    其中$varphi(m)$为欧拉函数,表示小于m且与m互质的正整数的个数。

    欧拉降幂

    $a^{x} mod m=a^{x+varphi(m) mod varphi(m)}mod m$

  • 相关阅读:
    排序算法(2)-冒泡排序及优化
    [转]Java泛型详解
    [转]Java泛型详解
    02-机器学习_(knn分类算法与应用)
    01-机器学习_(python数据类型详解)
    流量运营项目说明
    数据仓库星型模型vs雪花模型
    数据仓库命名规范
    数据仓库建模
    数据仓库
  • 原文地址:https://www.cnblogs.com/computer-luo/p/9459404.html
Copyright © 2011-2022 走看看