2018-07-12数论②

版权声明: https://blog.csdn.net/zjh_2017/article/details/81022563

初等数论

线性筛

v数组记录每个数的最小质因子

CODE

int v[MAX_N],prime[MAX_N];
void primes(int n)
{
    for (int i=2;i<=n;++i)
    {
        if (v[i]==0)//i是质数 
        {
            v[i]=i;//i的最小质因子就是它本身 
            prime[++m]=i;
        }
        //给当前的数i乘上一个质因子 
        for (int j=1;j<=m;++j)
        {
            //i有比prime[j]更小的质因子,或者超出n的范围 
            if (prime[j]>v[i]||prime[j]>n/i) break;
            //prime[j]是合数i*prime[j]的最小质因子 
            v[i*prime[j]]=prime[j];
            //保证prime[j]比i的最小质因子小(或等于) 
        }
    }
    for (int i=1;i<=m;++i)
    cout<<prime[i]<<endl;
}

素数定理

#1.唯一分解定理

任何一个大于1的正整数都能唯一分解为有限个质数的乘积

#2.费马小定理

p是质数, a p a ( m o d p )
(当欧拉定理的n为p时)

p是质数,a、p互质, a p 1 1 ( m o d p )

欧几里得算法

这里

扩展欧几里得算法

这里

BSGS(小步大步法)

Baby Step,Giant Step算法
问题:a,p互质,求一个整数x,使得 a x b ( m o d p )
解:把 b a j m o d p 插入一个Hash表。计算出 ( a t ) i m o d p ,在Hash表中查找是否存在对应的j。

CODE

hash.end()表示指向空,所以无解

int baby_step_giant_step(int a,int b,int p)
{
    map<int,int> hash;
    hash.clear();
    b%=p;
    int t=(int)sqrt(p)+1;
    for (int j=0;j<t;++j)
    {
        int val=(long long)b*power(a,j,p)%p;//b*a^j
        hash[val]=j;//插入Hash表 
    }
    a=power(a,t,p);//a^t
    if (a==0) return b==0?1:-1;
    for (int i=0;i<=t;++i)
    {
        int val=power(a,i,p);//(a^t)^i
        //查找Hash表 
        int j=hash.find(val)==hash.end()?-1:hash[val];
        if (j>=0&&i*t-j>=0) return i*t-j;
    }
    return -1;
}

猜你喜欢

转载自blog.csdn.net/zjh_2017/article/details/81022563