1. 程式人生 > 其它 >NOIP2003 普及組 洛谷P1045 麥森數 (快速冪+高精度)

NOIP2003 普及組 洛谷P1045 麥森數 (快速冪+高精度)

有兩個問題:求位數和求後500位的數。

求位數:最後減去1對答案的位數是不影響的,就是求2p的位數,直接有公式log10(2)*p+1;

求後500位的數:容易想到快速冪和高精度;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int p,f[1001],/*基數*/res[1001],/*記錄答案*/sav[1001]/*中間陣列*/;
 4 
 5 void work_1(){//記錄答案 
 6     memset(sav,0,sizeof(sav));//中間陣列每次用時初始化為0
 7     for(int i=1;i<=500;i++)//最後500位 
 8
for(int j=1;j<=500;j++)//兩層迴圈:高精乘法的精髓 9 sav[i+j-1]+=res[i]*f[j];//先計算每一位上的值(不進位) 10 for(int i=1;i<=500;i++){//處理進位 11 sav[i+1]+=sav[i]/10; 12 sav[i]%=10; 13 } 14 memcpy(res,sav,sizeof(res));//把sav的值賦給res 15 } 16 17 void work_2(){//基數相乘 18 memset(sav,0,sizeof
(sav)); 19 for(int i=1;i<=500;i++) 20 for(int j=1;j<=500;j++) 21 sav[i+j-1]+=f[i]*f[j]; 22 for(int i=1;i<=500;i++){ 23 sav[i+1]+=sav[i]/10; 24 sav[i]%=10; 25 } 26 memcpy(f,sav,sizeof(f)); 27 } 28 29 int main(){ 30 scanf("%d",&p); 31 printf("
%d\n",(int)(log10(2)*p+1));//求位數 32 res[1]=1;f[1]=2;//高精度賦初值 33 while(p){//快速冪模板 34 if(p&1) work_1(); 35 work_2();//基數相乘 36 p>>=1; 37 } 38 res[1]-=1;//最後要減1 39 for(int i=500;i>=1;i--){ 40 if(i!=500 && i%50==0) cout<<endl<<res[i];//每50個數要換行 41 else cout<<res[i]; 42 } 43 return 0; 44 }