2018-07-12數論②
阿新 • • 發佈:2018-12-08
初等數論
線性篩
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是質數,
(當尤拉定理的n為p時)
或
p是質數,a、p互質,
歐幾里得演算法
見這裡
擴充套件歐幾里得演算法
見這裡
BSGS(小步大步法)
Baby Step,Giant Step演算法
問題:a,p互質,求一個整數x,使得
解:把
插入一個Hash表。計算出
,在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;
}