1. 程式人生 > >2018-07-12數論②

2018-07-12數論②

初等數論

線性篩

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;
}