1. 程式人生 > >快速冪+分治(洛谷P1045 麥森數 noip2003)

快速冪+分治(洛谷P1045 麥森數 noip2003)

高精 進制 素數 str c++ efi ref == com

形如技術分享的素數稱為麥森數,這時技術分享一定也是個素數。但反過來不一定,即如果技術分享是個素數,技術分享不一定也是素數。到1998年底,人們已找到了37個麥森數。最大的一個是技術分享,它有909526位。麥森數有許多重要應用,它與完全數密切相關。

任務:從文件中輸入技術分享技術分享),計算技術分享的位數和最後500位數字(用十進制高精度數表示)

輸入格式:

文件中只包含一個整數技術分享技術分享

輸出格式:

第一行:十進制高精度數技術分享的位數。

第2-11行:十進制高精度數技術分享的最後500位數字。(每行輸出50位,共輸出10行,不足500位時高位補0)

不必驗證技術分享技術分享是否為素數。

輸入樣例#1:
1279
輸出樣例#1:
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
文庫大神的解析
我就不多說了,放上代碼~
#include<bits/stdc++.h>
#define maxn 40000
#define inf 999990
using namespace std;
int n;
int ans[maxn],s[maxn];

void solve(int x)
{
  if(x==0)
    return ;
  solve(x/2);
  for(int i=1;i<=500;i++)//順序從低到高高精度乘法 
    for(int j=1;j<=500;j++)
    {
	   if(x%2==0) ans[i+j-1]+=s[i]*s[j];
	   else  ans[i+j-1]+=s[i]*s[j]*2;
	}
   for(int i=1;i<=500;i++)
     {
	    s[i]=ans[i]%10;
	    ans[i+1]+=ans[i]/10;
	 }
	 memset(ans,0,sizeof(ans));//因為ans作為一個介質的功效,要隨即清零 
}

int main()
{
	cin>>n;
	cout<<int(log(2)/log(10)*n+1)<<endl;//換底公式, 
	s[1]=1;//important!!! 
	solve(n);
	for(int i=500;i>=2;i--)
	{
	   cout<<s[i];
	   if(i%50==1) cout<<endl;
	}
	cout<<s[1]-1<<endl;
    return 0;
}


快速冪+分治(洛谷P1045 麥森數 noip2003)