POJ1845 數論 二分快速取餘

2022-09-20 03:27:09 字數 2859 閱讀 8223

大致題意:

求a^b的所有約數(即因子)之和,並對其取模 9901再輸出。

解題思路:

應用定理主要有三個:

(1)   整數的唯一分解定理:

任意正整數都有且只有一種方式寫出其素因子的乘積表示式。

a=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均為素數

(2)   約數和公式:

對於已經分解的整數a=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)

有a的所有因子之和為

s = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)

(3)   同餘模公式:

(a+b)%m=(a%m+b%m)%m

(a*b)%m=(a%m*b%m)%m

有了上面的數學基礎,那麼本題解法就很簡單了:

1: 對a進行素因子分解

分解a的方法:

a首先對第乙個素數2不斷取模,a%2==0時 ,記錄2出現的次數+1,a/=2;

當a%2!=0時,則a對下乙個連續素數3不斷取模...

以此類推,直到a==1為止。

注意特殊判定,當a本身就是素數時,無法分解,它自己就是其本身的素數分解式。

最後得到a = p1^k1 * p2^k2 * p3^k3 *...* pn^kn.

故 a^b = p1^(k1*b) * p2^(k2*b) *...* pn^(kn*b);

2:a^b的所有約數之和為:

sum = [1+p1+p1^2+...+p1^(a1*b)] * [1+p2+p2^2+...+p2^(a2*b)] *...* [1+pn+pn^2+...+pn^(an*b)].

3: 用遞迴二分求等比數列1+pi+pi^2+pi^3+...+pi^n:

(1)若n為奇數,一共有偶數項,則:

1 + p + p^2 + p^3 +...+ p^n

= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2) * (1+p^(n/2+1))

=(1 + p + p^2 +...+ p^(n/2))* (1 + p^(n/2+1))

上式加粗的前半部分恰好就是原式的一半,那麼只需要不斷遞迴二分求和就可以了,後半部分為冪次式,將在下面第4點講述計算方法。

(2)若n為偶數,一共有奇數項,則:

1 + p + p^2 + p^3 +...+ p^n

= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2-1) * (1+p^(n/2+1)) + p^(n/2)

=(1 + p + p^2 +...+ p^(n/2-1))* (1+p^(n/2+1)) + p^(n/2);

上式加粗的前半部分恰好就是原式的一半,依然遞迴求解

4:反覆平方法計算冪次式p^n

這是本題關鍵所在,求n次冪方法的好壞,決定了本題是否tle。

以p=2,n=8為例

常規是通過連乘法求冪,即2^8=2*2*2*2*2*2*2*2

這樣做的要做8次乘法

而反覆平方法則不同,

定義冪sq=1,再檢查n是否大於0,

while,迴圈過程若發現n為奇數,則把此時的p值乘到sq

則sq=256就是所求,顯然反覆平方法只做了3次乘法

//

memory time

//336k 0ms

#include

using

namespace

std;

const

int size=10000

;const

int mod=9901

;__int64 sum(__int64 p,__int64 n);

//遞迴二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod

__int64 power(__int64 p,__int64 n); //

反覆平方法求 (p^n)%mod

int main(void

) k++;

}if(i==2) //

奇偶法 i++;

else

i+=2

; }

/*特殊判定:分解整數a (a為質數)

*/if(a!=1

)

int ans=1; //

約數和for(i=0;i)

ans=(ans*(sum(p[i],n[i]*b)%mod))%mod; //

n[i]*b可能會超過int,因此用__int64

cout

}return0;

}__int64 sum(__int64 p,__int64 n)

//遞迴二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod

__int64 power(__int64 p,__int64 n)

//反覆平方法求(p^n)%mod

return

sq;}

view code

**自:優you

數論 二分快速取餘

求12345 12345的所有約數 即因子 之和,並對其取模9901再輸出。key格式 ctf 這裡存在三個有趣的數學定理 1 整數唯一分解定理 2 約數和公式 3 同餘模公式 includeusing namespace std const int size 10000 const int mod...

poj 1845 Sumdiv 數論 二分

剛開始學習數論,不知道該從哪方面學起,就找了這道題做做,希望通過做題能找到學習數論的方向。花了有兩天的時間終於弄懂了這題的思想,恩,數論真的很神奇!題意是 求a b的所有因子的和取餘9901後的結果。用到的知識點有 1 素因子分解唯一性定理 任意正整數都能用一種方式且只有一種方式寫出素數的乘積。如 ...

POJ 1845 Sumdiv 質因數分解 二分

關於質因數分解,模板見 二分法思想 選定乙個要進行比較的目標,在區間 l,r 之間不斷二分,直到取到與目標相等的值。include include include using namespace std typedef long long ll const int n 10000 const int...