日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 1845

發布時間:2025/4/16 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1845 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大致題意:

求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本身就是素數時,無法分解,它自己就是其本身的素數分解式。

(自己寫的:對素數(素數p0,p1,......p(n-1),pn)進行取余,pi*pi>=a時結束
首先從第一個素數p1開始,當p%p1==0時對該素數進行記錄,說明素數p1可以組成p分解后的素因子(p%p1!=0時結束),對下一個素數ai進行判斷
當p%pi==0時開始記錄循環的次數,然后p/=pi進行循環(p%p1!=0時結束對素數pi的處理,進行對下一個素數pi+1進行處理)直到p==1時結束循環。)

最后得到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、

點擊查看快速冪運算講解

#include <cstring> using namespace std; int s[10010];//用于存儲分解后的素數因子 int n[10010];//用于存儲分解后的素數因子的冪指數的值 const int mod=9901; long long pow(long long p,long long n)//快速冪運算 {long long ans=1;while(n){if(n&1)ans=(ans*p)%mod;n/=2;p=(p*p)%mod;}return ans; } long long sum(long long a,long long n)//等比數列求和 {if(n==0)return 1;if(n&1)//n是奇數的情況if(n&1)等于if(n%2==1)return (sum(a,n/2)*(pow(a,n/2+1)+1))%mod;elsereturn (sum(a,n/2-1)*(1+pow(a,n/2+1))+pow(a,n/2))%mod; } int main() {long long a,b;int i,j;while(cin>>a>>b){int k=0;for(i=2;i*i<=a;)//結束條件{if(a%i==0)s[k]=i;n[k]=0;while(a%i==0)//判斷循多少次,即冪指數的值{n[k]+=1;a/=i;}k++;if(i==2)//奇偶法求素數因子,(但是自己感覺這種方法有點BUG例如9不是素數,但著這種方法會把9計算進去,不如用素數打表的方法,但是篩發打表又會超時)i++;elsei+=2;//也可以在開頭用for(i=2;i*i<a;i==2?i++:i+=2)語句進行判斷}if(a!=1)//當輸入的a本身就是素數的處理{s[k]=a;n[k++]=1;}long long ans=1;for(i=0;i<k;i++)ans=(ans%mod*(sum(s[i],n[i]*b)%mod))%mod;//用到了(3)同于模公式(a*b)%m=(a%m*b%m)%mcout<<ans<<endl;}return 0; }

用素數打表法把素數求出來:

#include<iostream> #include <cstring> #define MAX 7500//題目中給出的a b<50000000,所一素數打表MAX到7500(大約)就行 using namespace std; int s[10010];//用于存儲分解后的素數因子 int n[10010];//用于存儲分解后的素數因子的冪指數的值 const int mod=9901; long long primer[MAX],primerNum[MAX]; int num; long long pow(long long p,long long n) {long long ans=1;while(n){if(n&1)ans=(ans*p)%mod;n/=2;p=(p*p)%mod;}return ans; } long long sum(long long a,long long n) {if(n==0)return 1;if(n&1)//n是奇數的情況if(n&1)等于if(n%2==1)return (sum(a,n/2)*(pow(a,n/2+1)+1))%mod;elsereturn (sum(a,n/2-1)*(1+pow(a,n/2+1))+pow(a,n/2))%mod; }int main() {long long a,b;int i,j;memset(primer,1,sizeof(primer));for(i=2;i<MAX;i++)//一個素數的倍數必然不是素數,就把他的倍數打掉for(int j=i+i;j<MAX;j+=i)primer[j]=0;for(i=2;i<MAX;i++)if(primer[i])primerNum[num++]=i;while(cin>>a>>b){int k=0;for(i=0;primerNum[i]*primerNum[i]<=a;i++){if(a%primerNum[i]==0)s[k]=primerNum[i];n[k]=0;while(a%primerNum[i]==0)//判斷循多少次,即冪指數的值{n[k]+=1;a/=primerNum[i];}k++;}if(a!=1)//當輸入的a本身就是素數的處理{s[k]=a;n[k++]=1;}long long ans=1;for(i=0;i<k;i++)ans=(ans%mod*(sum(s[i],n[i]*b)%mod))%mod;//用到了(3)同于模公式(a*b)%m=(a%m*b%m)%mcout<<ans<<endl;}return 0; }

總結

以上是生活随笔為你收集整理的POJ 1845的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。