原题
题目描述
形如(2^{P}-1)的素数称为麦森数,这时(P)一定也是个素数。但反过来不一定,即如果(P)是个素数,(2^{P}-1)不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是(P=3021377),它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入(P)((1000<P<3100000)),计算(2^{P}-1)的位数和最后(500)位数字(用十进制高精度数表示)
输入格式
文件中只包含一个整数(P)((1000<P<3100000))
输出格式
第一行:十进制高精度数2P−12^{P}-12P−1的位数。
第2-11行:十进制高精度数2P−12^{P}-12P−1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证(2^{P}-1)与(P)是否为素数。
输入
1279
输出
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
说明/提示
【题目来源】
NOIP 2003 普及组第四题
题解
思路
《普及组》
考虑(50\%)分数:大暴力大模拟。
用纯暴力||快速幂 计算
代码
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f , N = 1e5+5;
typedef long long ll;
typedef unsigned long long ull ;
inline ll read(){
ll ret = 0;
char ch = ' ',c = getchar();
while(!isdigit(c))ch='-',c = getchar();
while(isdigit(c))ret = (ret<<1) + (ret<<3) + c - '0',c = getchar();
if(ch == '-')ret = - ret;
return ret;
}
struct haa{
int len;
short a[N];
void init(){
memset(a,0,sizeof(a));
len = 1;
}
void print(){
for(int i = len ; i >= 1 ; i --)
printf("%d",a[i]);
}
};
int n;
inline haa operator * (const haa& a,const haa& b){
haa t;
t.init();
t.len = a.len + b.len + 1;
for(int i = 1 ; i <= a.len ; i ++)
for(int j = 1 ; j <= b.len ; j ++){
if(i+j>505)continue;
t.a[i+j-1] += a.a[i] * b.a[j],
t.a[i+j] += t.a[i+j-1] / 10,
t.a[i+j-1] %= 10;
}
while(t.len && !t.a[t.len])
t.len --;
return t;
}
inline haa qpow(haa a,int b){
haa ret;
ret.init();
ret.a[1]=1;
while(b){
if(b&1)
ret = ret * a;
a = a * a;
b >>= 1;
}
return ret;
}
signed main(){
n = read();
haa a;a.init(),a.a[1] = 2;
haa ans = qpow(a,n);
ans.a[1]--;
printf("%d
",int(1.0*n/log2(10)+1));
for(int i = 9 ; i >= 0 ; i --,puts(""))
for(int j = i * 50 + 50 ; j > i * 50 ; j --)
printf("%d",ans.a[j]);
return 0;
}