NOIP数论总结

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/CoolKid_cwm/article/details/53043602

1.筛法求素数

利用筛法求素数可以在线性时间内求出1~n区间内所有的素数

void sieve(int n){
    int m=sqrt(n+0.5);
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=m;i++)
        for(int j=i*i;j<=n;j+=i) vis[j]=1;
}//筛素数

void GetPrimeTable(int n){
    sieve(n);
    int c=0;
    for(int i=2;i<=n;i++) if(!vis[i]) prime[c++] = i;
}//把素数全部放在prime数组里面

2.欧几里得

欧几里得

辗转相除法求a,b的最大公约数

int gcd(int a,int b){
    return b==0? a:gcd(b,a%b);
}//递归实现

int GCD(int a,int b){
    int r=b%a;
    while(r){
        b=a;
        a=r;
        r=b%a;
    }
    return a;
}//非递归实现

扩展欧几里得

求解方程ax+by=gcd(a,b)的一组解,并且使|x|+|y|的值最小

void exgcd(int a,int b,int &d,int &x,int &y){//注意d,x,y均为引用
    if(!b){ d=a;x=1;y=0; }
    else{
        exgcd(b,a%b,d,y,x);
        y-=(a/b)*x;
    }
}

3.模运算

除除法外模运算符合交换律和结合律

二进制快速幂

apmodn的值

long long quickpow(long long a,long long p,long long n){//a,p,n含义如上
    long long res=1;
    while(p){
        if(p&1) res=res*a%n;
        a=a*a%n;
        p>>=1;
    }
    return res;
}

4.欧拉函数

欧拉函数公式如下:
欧拉函数

int Euler_Phi(int n){
    int ans=n;
    for(int i=2;i<=n;i++) if(n%i==0){
        ans=ans/i*(i-1);
        while(n%i==0) n/=i;
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}//求单个数的欧拉函数
//筛法求欧拉函数表
void Phi_Table(int n){
    memset(phi,0,sizeof(phi));
    phi[1]=1;
    for(int i=2;i<=n;i++) if(!phi[i])
        for(int j=i;j<=n;j+=i){
            if(!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
}

5.唯一分解定理

一个数可以唯一分为几个不同质数的的乘积,数学表达式如下

n=pa11pa22pa33pa44pakk

void Divide(int n){
    for(int i=2;i<=n;i++){
        while(n%i==0){
            a[i]++;
            n/=i;
        }
    }
}//表示n=i^a[i]

6.例题

1.首遇lancer

题目原址
题目大意:求n的因数的因数个数和
分析:利用唯一分解定理可以知道任意一个数n的因子个数为(a1+1)(a2+1)(a3+1)(ak+1)
因此这些因数的因数个数和应为ans=kj=1aj+1i=1i
根据求和公式可以知道ans=kj=1(aj+1)(aj+2)2
这样就可以在O(n)的时间复杂度内解决上述问题。

例题持续更新…

展开阅读全文

没有更多推荐了,返回首页