Files
exercises/NOIP2003J_bigint.cpp
T
2026-09-05 11:05:50 +08:00

105 lines
2.6 KiB
C++

#include <cmath>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
/// 只处理 500 位!
class BigInt {
public:
using bigint = vector<unsigned long long>;
static constexpr unsigned int BASE_DIGITS = 8;
const unsigned long long BASE = static_cast<unsigned long long>(std::pow(10, BASE_DIGITS));
static constexpr size_t TARGET_SIZE = 125;
bigint value;
BigInt() : value({0}) { organize(); }
BigInt(bigint v) : value(std::move(v)) { organize(); }
BigInt(unsigned long long v) {
value.push_back(v);
organize();
}
void organize() {
value.resize(TARGET_SIZE, 0);
for (int i = 0; i < TARGET_SIZE - 1; i++) {
value[i + 1] += value[i] / BASE;
value[i] %= BASE;
}
value[TARGET_SIZE - 1] %= BASE;
}
BigInt& operator=(const BigInt& other) {
value = other.value;
organize();
return *this;
}
BigInt operator*(const BigInt& other) const {
BigInt ans(0);
for (int i = 0; i < TARGET_SIZE; i++) {
for (int j = 0; i + j < TARGET_SIZE; j++) {
ans.value[i + j] += value[i] * other.value[j];
}
}
ans.organize();
return ans;
}
BigInt operator*(const unsigned long other) const {
BigInt ans(*this);
ans.value[0] *= other;
ans.organize();
return ans;
}
template <typename T>
BigInt operator*=(const T& other) {
*this = *this * other;
return *this;
}
[[nodiscard]] BigInt pow(unsigned int exp) const {
if (exp == 0) { return {1}; }
if (exp == 1) { return *this; }
BigInt ans = (*this * *this).pow(exp / 2);
if (exp % 2 == 1) {
ans *= *this;
}
return ans;
}
[[nodiscard]] string to_string(size_t digits = 500) const {
string s;
for (int i = 0; i < TARGET_SIZE; i++) {
string current = std::to_string(value[i]);
if (current.size() < BASE_DIGITS) {
current.insert(0, BASE_DIGITS - current.size(), '0');
}
s.insert(0, current);
}
return s.substr(s.size() - digits, s.size());
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
unsigned int exp;
cin >> exp;
cout << floor(exp * log10(2)) + 1 << endl;
BigInt ans = BigInt(2).pow(exp);
ans.value[0] -= 1; // 2^n 没问题
string s = ans.to_string(500);
for (int i = 0; i < 500; i += 50) {
cout << s.substr(i, 50) << endl;
}
return 0;
}