P1045 [NOIP2003 普及組] 麥森數
阿新 • • 發佈:2021-07-21
大整數+快速冪
複雜度\(O(500*500*log(p))\)
其中,位數的計算方法:
由於\(2^p\)最低位不會是0,所以\(2^p-1\)和\(2^p\)有同樣的位數,由於\(10^x\)的位數為\(x + 1\),所以令\(2^p=10^x\)有\(x = \log_{10}^{2^p}=p*\log_{10}^{2}\),所以位數為\(p*\log_{10}^{2} + 1\)
#include<iostream> #include<cstring> #include<cmath> using namespace std; const int N = 500; int a[N]; int ans[N]; int backup[N]; int p; void mul(int *a, int *b){ memset(backup, 0, sizeof backup); for(int i = 0; i < N; i ++) for(int j = 0; j < N; j ++){ if(i + j >= N) continue; backup[i + j] += a[i] * b[j]; } int t = 0; for(int i = 0; i < N; i ++){ backup[i] += t; t = backup[i] / 10; backup[i] %= 10; } memcpy(a, backup, sizeof backup); } void ksm(int e){ a[0] = 2, ans[0] = 1; while(e){ if(e & 1) mul(ans, a); mul(a, a); e >>= 1; } } int main(){ cin >> p; ksm(p); ans[0] -= 1; if(ans[0] < 0){ ans[0] += 10; for(int i = 1; i < 500; i ++) if(ans[i] == 0) ans[i] = 9; else{ ans[i] --; break; } } cout << int(log10(2) * p + 1) << endl; for(int i = N - 1, k = 1; i >= 0; i --, k ++) cout << ans[i] << (k % 50 ? "" : "\n"); return 0; }