阶乘之和(高精度)题目描述
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 100
struct Bigint {
int len, a[maxn];
Bigint(int x = 0) { //构造函数,进行初始化
memset(a, 0, sizeof(a));
for(len = 1; x; len++) { //x由循环内执行改变,为0时跳出循环
a[len] = x % 10;
x /= 10;
}
len--;
}
int &operator[](int i) { //重载[],直接用x[i]代表x.a[i]
return a[i];
}
void flatten(int l) { //处理1到l范围内的进位并重置长度
len = l;
for(int i = 1; i <= len; i++) {
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
for(; !a[len]; ) len--; //l涉及进位,不是有效长度,处理后可能存在剩余0,需要重置长度为有效长度
}
void print() {
for(int i = max(1, len); i >= 1; i--) printf("%d", a[i]);
}
};
Bigint operator+(Bigint a, Bigint b) { //表示两个 Bigint类相加
Bigint c;
int len = max(a.len, b.len);
for(int i = 1; i <= len; i++)
c[i] = a[i] + b[i];
c.flatten(len + 1); //两者相加进位后不超过len+1
return c;
}
Bigint operator*(Bigint a, int b) { //表示Bigint类乘整型变量
Bigint c;
int len = a.len;
for(int i = 1; i <= len; i++)
c[i] = a[i] * b;
c.flatten(len + 11); // len+11满足大整数相乘进位
return c;
}
int main() {
Bigint ans(0), fac(1); //分别用0和1初始化ans和fac
int m;
cin >> m;
for(int i = 1; i <= m; i++) {
fac = fac * i;
ans = ans + fac;
}
ans.print();
return 0;
}
大整数重载减号进行数组运算
Bigint operator-(Bigint z, Bigint b) {
Bigint c;
int len = z.len;
for(int i = 1; i <= len; i++) {
if(z[i] < b[i]) {
z[i] += 10;
z[i+1] -= 1;
}
c[i] = z[i] - b[i];
}
c.len = len;
for(; !c[len]; ) c.len--;
return c;
}
大整数重载乘号进行数组运算
Bigint operator*(Bigint a, Bigint b) {
Bigint c;
int lena = a.len, lenb = b.len;
for(int i = 1; i <= lena; i++) {
for(int j = 1; j <= lenb; j++)
c[i + j - 1] += a[i] * b[j];
}
c.flatten(lena + lenb);
return c;
}
麦森数题目描述
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 100001
#define POST 500
struct Bigint {
int len, a[MAXN];
Bigint(int x = 0) {
memset(a, 0, sizeof(a));
for(len = 1; x; len++) {
a[len] = x % 10;
x /= 10;
}
len--;
}
int &operator[](int i) {
return a[i];
}
void flatten(int l) {
len = l;
for(int i = 1; i <= len; i++) {
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
for(; !a[len]; ) len--;
}
void print() {
for (int i = POST; i >= 1; --i) {
printf("%d", a[i]);
if (!((i-1) % 50 )) printf("\n");
}
}
};
Bigint operator*(Bigint a, Bigint b) {
Bigint c;
int lena = min(POST, a.len), lenb = min(POST, b.len);
for(int i = 1; i <= lena; i++) {
for(int j = 1; j <= lenb; j++)
c[i + j - 1] += a[i] * b[j];
}
c.flatten(lena + lenb);
return c;
}
//采用了高精和快速幂方法
int main() {
Bigint res(1), f(2);
int p;
cin >> p;
printf("%d\n", (int)(log10(2)*p+1));
while(p != 0) {
if(p % 2 == 1) //等同于n&1, 如果n的当前末位为1
res = res * f;
p /= 2; //等同于n >>= 1, n往右移一位
f = f * f;
}
res[1] -= 1;
res.print();
return 0;
}