數論1 素數 約數 反素數

2021-10-23 18:19:45 字數 2716 閱讀 5654

素數是指只能被自身整除和被1整除的數(大於1的自然數,1不是素數)不是素數的數為合數

常見的題型有:素數的判定+素數的篩選兩種題型

素數的篩選:

const

int n=

1000001

;int primes[n]

,cnt;

//primes存素數 cnt 存素數的個數

bool st[n]

;//存數n是否被篩過

void

getprimes

(int n)

}}

若整數n除以整數d的餘數是0 ,即d能整除n,則稱d是n的約數, n是d的倍數

對於乙個數我們可以質因數分解,所以對於每個數n

我們可以分解成 p1 ^ c1+p2 ^ c2+……+px ^ cx

而約數個數也就是(c1+1) * (c2+1) * …… (cx+1)

而約數和就是 (1+p1+p1^ 2 +p1^ 3+p1^ 4……+p1^ c1) (1+1+p2+p2^ 2+p2^ 3+p2^ 4…… +p2^ c2)……(1+pn+pn^ 2+pn^ 3……pn^ cn)

#include

#include

using

namespace std;

long

long prime[

3000100

],t[

3000100

],e[

3000100];

int vist[

3000100];

intmain()

for(

int j=

1;j<=num;j++

)//用最小質因子去篩

else

//不是倍數的時候 }}

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,t[i]);

//輸出答案

return0;

}

既然有約數個數,那麼跟定有約數和,現在我們就來講一下怎麼計算約數和。

根據上面約數個數的思想,我們也用分類討論來計算約數和。

同樣我們要定義兩個陣列,乙個是t,t[i]表示i的約數和,同樣我們也要乙個輔助的陣列e,e[i]表示不能被最小質因子整除的約數的和。

首先如果x是質數的話,約數只有自己和1,那麼t[x]=x+1,而不能被最小質因子整除的數也只有1,所以e[x]=1。

然後我們再用i*prime[j]去表示非質數的x,同樣,也分i可以整除prime[j]和不能整除。

不可以整除的話,意味著t[i]和t[prime[j]]這兩個是沒有重複部分的,因為他們這兩個數是互質的,證明一下吧,因為prime[j]是個質數,所以如果不是互質的話只有一種可能,就是i是prime[j]的倍數(這就是我們要這麼分類討論的原因,上面的分類討論也是因為這個)。所以t[x]=t[i]*prime[j]+t[i],化簡一下就是t[x]=t[i] * (prime[j]+1)。而e因為不是倍數所以e[x]=t[i]

如果i是prime[j]的倍數的話因為他們中有重複的,重複的部分就是可以被最小質因子整除的約數和,也就是t[i]-e[i],那麼我們為什麼不用e陣列直接存這個呢?因為不方便計算啊。所以我們就是t[x]=t[i] * prime[j]+t[i]-(t[i]-e[i]),化簡一下就是t[x]=t[i]*prime[j]+e[i],而e因為是倍數所以我們要繼承一下e[x]=e[i],這樣就計算完了。

#include

#include

using

namespace std;

long

long vist[

3000100

],prime[

3000100

],t[

3000100

],e[

3000100];

intmain()

for(

int j=

1;j<=num;j++

)else

//不是倍數 }}

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,t[i]);

//輸出

return0;

}

反素數

#include

#include

using

namespace std;

typedef

unsigned

long

long ull;

#define inf ((ull)1)<<62

const

int maxn =

50000

;ull ans;

int type,k;

int d[maxn]

;int prime=

;void

create_table()

}void

dfs(

int pos,ull value,

int num)

for(

int i =

1; i <=

63; i++)}

intmain()

else

}return0;

}

數論基礎之素數,約數

關於約數 唯一分解定理 任何數都可由素因子之積構成 int p 100 a 100 cnt void divide int n if n 1 for int i 1 i cnt i cout 方法2 離線做法,預處理出乙個質因子樹。預處理o nlogn 查詢乙個數o logn void init v...

約數個數 反素數

對於任何正整數x,其約數的個數記作g x 例如g 1 1 g 6 4。如果某個正整數x滿足 對於任意的小於x的正整數 i,都有g x g i 則稱x為反素數。例如,整數1,2,4,6等都是反素數。現在給定乙個數n,請求出不超過n的最大的反素數。輸入格式 乙個正整數n。輸出格式 乙個整數,表示不超過n...

python打反素數 反素數求解 反素數打表

問題描述 對於任何正整數x,起約數的個數記做g x 例如g 1 1,g 6 4.如果某個正整數x滿足 對於任意i 0 現在給乙個n,求出不超過n的最大的反素數.比如 輸入1000 輸出 840 思維過程 求 1.n 中約數在大的反素數 求約數最多的數 如果求約數的個數 756 2 2 3 3 7 1...