數論從這裡開始 乙個數的因數

2022-08-21 08:51:15 字數 2817 閱讀 4020

數論又多又難,該從哪開始學呢?不如先思考一下下面這個問題:

對於乙個自然數n,它的因數是什麼?

一、因數的篩法

1.最簡單的暴力

相信只要你有一點數學和程式設計基礎的話,都會想到下面這個最簡單暴力的方法:

1

int find_factor(intx)2

對,只要從1到n遍歷一遍,看看是不是n的因數就解決了。

但是這樣的話有乙個缺點,該演算法的時間複雜度為o(n),資料稍微一大,就超時了。

2.修改後的篩法

那麼我們能不能稍微改進一下這個演算法呢?答案是可以的,我們都知道乙個數的因數一定是成對出現的,那麼對於每一組裡小的那個因數,它的大小不會超過

,利用這一點我們可以將我們的演算法做如下改進:

1

int find_factor(intx)2

10return

cnt;

11 }

這樣一來,我們的時間複雜度就變為了o(

),可以解決更大範圍的資料了。上面的篩法也是在大多數題目中適用的。

3.加強版篩法

但是還是有更加善良的出題人,想要繼續考察我們,這就需要我們學習專業的數學知識了。我們先來看下面兩個概念:

·分解質因數:把n表示為質數相乘的形式,如30=2×3×5。

我們可以用下面的**實現分解質因數(時間複雜度o(

)):

1 #include 2

3using

namespace

std;45

void

resolved()619

if(temp!=1) printf("

%d",temp); //

當n為質數

20return;21

}2223int

main()

24

分解質因數

(還有乙個時間複雜度為o(

)的演算法,日後再補)

既然這些因數都是質數,我們可以把乙個數n的分解質因數表示為:

其中,p1、p2、p3…pk是由小到大的質數,如:36=2×2×3×3=22×32。

·約數個數定理:對於乙個大於1正整數n可以分解質因數:

則n的正約數的個數就是:

其中a1、a2、a3…ak是p1、p2、p3…pk的指數。

感覺不太好理解?我們來看下面幾個例項:

(1)10=2×5=21×51

10的因子:1(20×50),2(21×50),5(20×51),10(21×51),

因子的個數=4=(1+1)×(1+1);

(2)36=2×2×3×3=22×32

36的因子:1(20×30),2(21×30),4(22×30),3(20×31),6(21×31),12(22×31),9(20×32),18(21×32),36(22×32),

因子的個數=9=(2+1)×(2+1);

看完這幾個例子,不知你感覺如何,接著我們用**來實現這個過程:

1

int find_factor(intx)2

12 p++;

13 cnt*=t;14}

15return

cnt;

16 }

這個方法不光可用用來求乙個數的因數的個數,還可以用來解與因數個數相關的問題。

二、約數個數定理的應用

我們來看下面幾個問題:

1.求1到n裡面約數最多的數的約數個數(n<=1018)

這個題注意資料!!!一看到這個資料我們就知道暴力是不可能實現的,那麼又如何使用上面的方法呢?如果用上面的方法進行列舉也是不可取的。

那麼我們來簡單分析下這個問題:

·我們知道每乙個數都可以用質因子的積表示,而約數的個數只與指數有關!

·我們知道pn>...>p3>p2>p1,那麼假設我們存在某乙個ak>a1 那麼我們交換pk與p1的指數,顯然約數個數不變,但是數變小了!

如:24=23×31和54=21×33。

·也就是說對於任何n,m如果pn>pm那麼an

m 要好一些。但是不是最優的,不確定,不過這已經為我們淘汰了許多不必要的情況了。

這樣使用dfs與之結合,列舉每乙個質因子的質數,保證其指數遞減,

然後我們就可以寫出**了:

1 #include 2

3using

namespace

std;45

int prime[25]=; //

存一下質數

6long

long

n,ans;78

//pos代表第幾個質數,num代表目前因子的個數,multi代表目前的數,len代表迴圈的次數

9void get_num_dfs(int pos,long

long num,long

long multi,int

len)

1020

return;21

}2223int

main()

2434

return0;

35 }

author : houge  date : 2019.5.27

update log : 

2019.5.30:修正了一處錯誤。

乙個數的約數的個數 質因數分解

problem description 乙個數,如果他的素數因子只包括2,3,5,7,則稱這個數為萌數,比如,下面這些數就是前20個萌數 1,2,3,4,5,6,7,8,9,10,12,14,15,16,18,20,21,24,25,27。現在給你乙個萌數,請程式設計計算它的約數的個數。比如,4是乙...

求乙個數的質因數(1個或n個)

在做 容斥原理 題時經常需要求出乙個數的質因子,而且不是所求數的位數很多,就是一次求n多數的質因子。下面分別給出兩種型別的 供拋磚引玉。第一種型別 用於每次只能求出乙個數的質因子,適用於題目中給的n的個數不是很多,但是n又特別大的情況。includeint main if n 1 應對 n 103 ...

239 判斷乙個數的所有因數的個數是偶數還是奇數

只需要你判斷因 數的個數是偶數個還是奇數個,那麼可以這麼做 濱湖 土豆 那只在計算質因數的過程 中統計一下當前質因數出現的次數,如果出現奇數次則結果為偶,然後可以立即返回 如果每個質因數的次數都是偶數,那麼結果為奇。如果該數是平方數 結果就為奇 否則就為偶了 如果乙個數是平方數,因數是奇數個 如果不...