QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#91235#6126. Sequence and SequenceGolovanov399AC ✓7582ms261916kbC++2016.8kb2023-03-27 20:20:272023-03-27 20:20:29

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-27 20:20:29]
  • 评测
  • 测评结果:AC
  • 用时:7582ms
  • 内存:261916kb
  • [2023-03-27 20:20:27]
  • 提交

answer

#include <bits/stdc++.h>

#include <algorithm>
#include <cctype>
#include <compare>
#include <cstdint>
#include <string>
#include <vector>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>



#include <type_traits>

using li = long long;
using LI = __int128_t;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;

template <typename> struct next_size;
template <typename T> using next_size_t = typename next_size<T>::type;
template <typename T> struct tag { using type = T; };

template <> struct next_size<int8_t> : tag<int16_t> {};
template <> struct next_size<int16_t> : tag<int32_t> {};
template <> struct next_size<int32_t> : tag<int64_t> {};
template <> struct next_size<int64_t> : tag<__int128_t> {};
template <> struct next_size<long long> : tag<__int128_t> {};

ld eps = 1e-8;
void set_eps(ld new_eps) {
	eps = new_eps;
}

template <typename T>
std::enable_if_t<std::is_integral_v<T>, int> sign(T x) {
	return x < 0 ? -1 : x > 0;
}

template <typename T>
std::enable_if_t<std::is_floating_point_v<T>, int> sign(T x) {
	return x < -eps ? -1 : x > eps;
}

using std::vector, std::strong_ordering;

struct BigInteger {
	using u32 = uint32_t;
	using u64 = uint64_t;
	using i64 =  int64_t;
	static constexpr u32 BASE = 1'000'000'000;
	static constexpr int BASE_LEN = [](u32 base) { int res = 0; while (base > 1) { base /= 10; ++res; } return res; }(BASE);

	vector<u32> digits;
	bool neg;

	BigInteger(long long x = 0): neg(false) {
		if (x < 0) {
			neg = true;
			x = -x;
		}
		while (x) {
			digits.push_back(x % BASE);
			x /= BASE;
		}
	}

	BigInteger(const std::string& s) {
		neg = false;
		digits = {};
		int i = (int)s.length() - 1;
		while (i >= 0 && std::isdigit(s[i])) {
			int j = i;
			while (j >= 0 && j > i - BASE_LEN && std::isdigit(s[j])) {
				--j;
			}
			digits.push_back(std::stoi(s.substr(j + 1, i - j)));
			i = j;
		}
		if (i > 0 || (i == 0 && s[i] != '-' && s[i] != '+')) {
			throw std::runtime_error("invalid biginteger");
		} else if (i == 0 && s[i] == '-') {
			neg = true;
		}
		shrink();
	}

	BigInteger from_int128(__int128_t x) {
		BigInteger res;
		if (x < 0) {
			res.neg = true;
			x = -x;
		}
		while (x) {
			res.digits.push_back(x % BASE);
			x /= BASE;
		}
		return res;
	}

	static BigInteger from_digits(const vector<u32>& dgs, bool neg = false) {
		BigInteger res;
		res.digits = dgs;
		res.neg = neg;
		return res;
	}

	void shrink() {
		while (!digits.empty() && !digits.back()) {
			digits.pop_back();
		}
		if (digits.empty()) {
			neg = false;
		}
	}

	int _cmp(const BigInteger& ot) const {
		if (digits.size() != ot.digits.size()) {
			return sign((int)digits.size() - (int)ot.digits.size());
		}
		for (int i = (int)digits.size() - 1; i >= 0; --i) {
			if (digits[i] != ot.digits[i]) {
				return sign((int)digits[i] - (int)ot.digits[i]);
			}
		}
		return 0;
	}

	void _add(const vector<u32>& dgs) {
		u32 carry = 0;
		if (dgs.size() > digits.size()) {
			digits.resize(dgs.size());
		}
		for (int i = 0; i < (int)digits.size() || i < (int)dgs.size(); ++i) {
			if (i < (int)digits.size()) {
				carry += digits[i];
			}
			if (i < (int)dgs.size()) {
				carry += dgs[i];
			}
			digits[i] = carry % BASE;
			carry /= BASE;
		}
		if (carry) {
			digits.push_back(carry);
		}
	}

	void _sub(const vector<u32>& dgs) {
		u32 carry = 0;
		for (int i = 0; i < (int)digits.size(); ++i) {
			if (i < (int)dgs.size()) {
				carry += dgs[i];
			}
			if (digits[i] >= carry) {
				digits[i] -= carry;
				carry = 0;
			} else {
				digits[i] += BASE;
				digits[i] -= carry;
				carry = 1;
			}
		}
		shrink();
	}

	static vector<u32> _mul(const vector<u32>& a, const vector<u32>& b) {
		if (a.empty() || b.empty()) {
			return {};
		}
		vector<u32> res(a.size() + b.size() - 1);
		u64 carry = 0;
		for (int i = 0; i < (int)a.size() + (int)b.size() - 1; ++i) {
			res[i] = carry % BASE;
			carry /= BASE;
			int from = std::max(0, i - (int)b.size() + 1);
			int to = std::min((int)a.size() - 1, i);
			for (int j = from; j <= to; ++j) {
				u64 tmp = (u64)a[j] * b[i - j];
				carry += tmp / BASE;
				res[i] += tmp % BASE;
				if (res[i] >= BASE) {
					res[i] -= BASE;
					carry += 1;
				}
			}
		}
		while (carry > 0) {
			res.push_back(carry % BASE);
			carry /= BASE;
		}
		return res;
	}

	static int _len(const vector<u32>& dgs) {
		if (dgs.empty()) {
			return 0;
		} else {
			return ((int)dgs.size() - 1) * BASE_LEN + std::to_string(dgs.back()).length();
		}
	}

	static vector<u32> _div(vector<u32> a, const vector<u32>& b) {
		vector<u32> res;
		u64 cur = 0;
		for (int i = (int)a.size() - 1; i >= (int)b.size() - 1; --i) {
			cur *= BASE;
			cur += a[i];
			u32 le = cur / (b.back() + 1);
			u32 ri = cur / b.back() + 1;
			while (ri > le + 1) {
				u32 k = le + (ri - le) / 2;

				u64 can = cur;
				bool ok = true;
				for (int j = 0; j < (int)b.size(); ++j) {
					if (j) {
						can = can * BASE + a[i - j];
					}
					if (can < (u64)b[(int)b.size() - 1 - j] * k) {
						ok = false;
						break;
					}
					can -= (u64)b[(int)b.size() - 1 - j] * k;
					if (can >= k) {
						break;
					}
				}
				(ok ? le : ri) = k;
			}
			u32 k = le;
			res.push_back(k);
			u64 carry = 0;
			for (int j = (int)b.size() - 1; j > 0; --j) {
				carry += (u64)b[(int)b.size() - 1 - j] * k;
				if (carry % BASE <= a[i - j]) {
					a[i - j] -= carry % BASE;
				} else {
					a[i - j] += BASE;
					a[i - j] -= carry % BASE;
					carry += BASE;
				}
				carry /= BASE;
			}
			carry += (u64)b.back() * k;
			cur -= carry;
		}
		reverse(res.begin(), res.end());
		return res;
	}

	BigInteger& operator +=(const BigInteger& ot) {
		if (neg == ot.neg) {
			_add(ot.digits);
		} else if (_cmp(ot) < 0) {
			neg = ot.neg;
			auto d = digits;
			digits = ot.digits;
			_sub(d);
		} else {
			_sub(ot.digits);
		}
		return *this;
	}

	BigInteger& operator -=(const BigInteger& ot) {
		if (neg == !ot.neg) {
			_add(ot.digits);
		} else if (_cmp(ot) < 0) {
			neg = !ot.neg;
			auto d = digits;
			digits = ot.digits;
			_sub(d);
		} else {
			_sub(ot.digits);
		}
		return *this;
	}

	BigInteger operator +(const BigInteger& ot) const {
		BigInteger res = *this;
		res += ot;
		return res;
	}

	BigInteger operator -(const BigInteger& ot) const {
		BigInteger res = *this;
		res -= ot;
		return res;
	}

	BigInteger operator -() const {
		auto res = *this;
		if (!digits.empty()) {
			res.neg ^= 1;
		}
		return res;
	}

	BigInteger& operator *=(const BigInteger& ot) {
		if (digits.empty() || ot.digits.empty()) {
			digits = {};
			neg = false;
			return *this;
		}
		digits = _mul(digits, ot.digits);
		neg ^= ot.neg;
		return *this;
	}

	BigInteger operator *(const BigInteger& ot) const {
		if (digits.empty() || ot.digits.empty()) {
			return from_digits({});
		}
		return from_digits(_mul(digits, ot.digits), neg ^ ot.neg);
	}

	BigInteger& operator /=(i64 x) {	// negative numbers are divided as in C++
		if (x == 0) {
			throw std::domain_error("division by zero");
		}
		if (x < 0) {
			neg ^= 1;
			x = -x;
		}
		u64 carry = 0;
		for (int i = (int)digits.size() - 1; i >= 0; --i) {
			carry *= BASE;
			carry += digits[i];
			digits[i] = carry / x;
			carry %= x;
		}
		shrink();
		return *this;
	}

	BigInteger operator /(i64 x) const {
		auto res = *this;
		res /= x;
		return res;
	}

	i64 operator %(i64 x) const {
		if (x == 0) {
			throw std::domain_error("division by zero");
		}
		bool flip = neg;
		if (x < 0) {
			flip ^= 1;
			x = -x;
		}
		u64 carry = 0;
		for (int i = (int)digits.size() - 1; i >= 0; --i) {
			carry *= BASE;
			carry += digits[i];
			carry %= x;
		}
		return (i64)carry * (flip ? -1 : 1);
	}

	BigInteger& operator %=(i64 x) {
		*this = *this % x;
		return *this;
	}

	BigInteger& operator /=(const BigInteger& ot) {
		if (ot.digits.empty()) {
			throw std::domain_error("division by zero");
		}
		if (digits.empty()) {
			return *this;
		}
		neg ^= ot.neg;
		digits = _div(digits, ot.digits);
		shrink();
		return *this;
	}

	BigInteger operator /(const BigInteger& ot) const {
		auto res = *this;
		res /= ot;
		return res;
	}

	strong_ordering operator <=>(const BigInteger& ot) const {
		if (neg != ot.neg) {
			return neg ? strong_ordering::less : strong_ordering::greater;
		} else {
			int s = _cmp(ot);
			if (neg) {
				s = -s;
			}
			return s < 0 ? strong_ordering::less : s > 0 ? strong_ordering::greater : strong_ordering::equal;
		}
	}

	bool operator ==(const BigInteger& ot) const {
		return neg == ot.neg && digits == ot.digits;
	}

	BigInteger pow(u32 x) const {
		if (!x) {
			return 1;
		}
		BigInteger res = 1;
		for (int i = 31 - __builtin_clz(x); i >= 0; --i) {
			res *= res;
			if ((x >> i) & 1) {
				res *= *this;
			}
		}
		return res;
	}

	std::string to_string() const {
		std::string s;
		std::ostringstream ss(s);
		ss << *this;
		return s;
	}

	void drop_digits(int cnt) {
		if (!cnt) {
			return;
		}
		int blocks = cnt / BASE_LEN;
		if (blocks >= (int)digits.size()) {
			digits = {};
			shrink();
			return;
		}
		digits.erase(digits.begin(), digits.begin() + blocks);
		int rem = cnt - blocks * BASE_LEN;
		if (rem) {
			const u32 tp = [](int deg) { u32 res = 1; while (deg--) { res *= 10; } return res; }(rem);
			for (int i = 0; i + 1 < (int)digits.size(); ++i) {
				digits[i] = digits[i] / tp + (digits[i + 1] % tp) * (BASE / tp);
			}
			digits.back() /= tp;
			shrink();
		}
	}

	void add_zeroes(int cnt) {
		if (digits.empty()) {
			return;
		}
		int blocks = (cnt + BASE_LEN - 1) / BASE_LEN;
		digits.resize(digits.size() + blocks);
		std::copy(digits.begin(), digits.begin() + (int)digits.size() - blocks, digits.begin() + blocks);
		std::fill(digits.begin(), digits.begin() + blocks, 0);
		drop_digits(blocks * BASE_LEN - cnt);
	}

	void leave_digits(int cnt) {
		int blocks = (cnt + BASE_LEN - 1) / BASE_LEN;
		if (blocks > (int)digits.size()) {
			return;
		}
		digits.resize(blocks);
		if (cnt != blocks * BASE_LEN) {
			int rem = cnt - (blocks - 1) * BASE_LEN;
			const u32 tp = [](int deg) { u32 res = 1; while (deg--) { res *= 10; } return res; }(rem);
			digits.back() %= tp;
		}
		shrink();
	}

	int length() const {
		return _len(digits);
	}

	int to_int() const {
		int res = 0;
		for (auto x : digits) {
			res = res * BASE + x;
		}
		if (neg) {
			res = -res;
		}
		return res;
	}

	long long to_long() const {
		long long res = 0;
		for (auto x : digits) {
			res = res * BASE + x;
		}
		if (neg) {
			res = -res;
		}
		return res;
	}

	friend std::ostream& operator <<(std::ostream& ostr, const BigInteger& num) {
		if (num.neg) {
			ostr << "-";
		}
		for (int i = (int)num.digits.size() - 1; i >= 0; --i) {
			if (i < (int)num.digits.size() - 1) {
				ostr << std::setfill('0') << std::setw(BASE_LEN);
			}
			ostr << num.digits[i];
		}
		if (num.digits.empty()) {
			ostr << "0";
		}
		return ostr;
	}

	friend std::istream& operator >>(std::istream& istr, BigInteger& num) {
		std::string s;
		istr >> s;
		num = BigInteger(s);
		return istr;
	}
};
#define all(x) (x).begin(), (x).end()

using namespace std;

int nxt() {
	int x;
	cin >> x;
	return x;
}

struct Fraction {
	BigInteger num;
	long long denom;

	Fraction(int x = 0): num(x), denom(1) {}
	Fraction(long long x): num(x), denom(1) {}
	Fraction(const BigInteger& n): num(n), denom(1) {}
	Fraction(int x, int y): num(x), denom(y) {
		cancel_out();
	}

	void cancel_out() {
		auto g = num % denom;
		g = gcd(g, denom);
		if (g > 1) {
			denom /= g;
			num /= g;
		}
	}

	Fraction& operator +=(const Fraction& ot) {
		num = num * ot.denom + ot.num * denom;
		denom *= ot.denom;
		cancel_out();
		return *this;
	}

	Fraction& operator -=(const Fraction& ot) {
		num = num * ot.denom - ot.num * denom;
		denom *= ot.denom;
		cancel_out();
		return *this;
	}

	Fraction& operator *=(const Fraction& ot) {
		num *= ot.num;
		denom *= ot.denom;
		cancel_out();
		return *this;
	}

	Fraction& operator /=(long long x) {
		denom *= x;
		cancel_out();
		return *this;
	}

	friend Fraction operator +(Fraction a, const Fraction& b) {
		return a += b;
	}

	friend Fraction operator -(Fraction a, const Fraction& b) {
		return a -= b;
	}

	friend Fraction operator *(Fraction a, const Fraction& b) {
		return a *= b;
	}

	Fraction operator -() const {
		auto res = *this;
		res.num *= -1;
		return res;
	}

	friend ostream& operator <<(ostream& ostr, const Fraction& f) {
		ostr << f.num;
		if (f.denom > 1) {
			ostr << "/" << f.denom;
		}
		return ostr;
	}
};

using Poly = vector<Fraction>;

Poly add(const Poly& a, const Poly& b) {
	Poly res(max(a.size(), b.size()));
	for (int i = 0; i < (int)a.size(); ++i) {
		res[i] += a[i];
	}
	for (int i = 0; i < (int)b.size(); ++i) {
		res[i] += b[i];
	}
	return res;
}

Poly sub(const Poly& a, const Poly& b) {
	Poly res(max(a.size(), b.size()));
	for (int i = 0; i < (int)a.size(); ++i) {
		res[i] += a[i];
	}
	for (int i = 0; i < (int)b.size(); ++i) {
		res[i] -= b[i];
	}
	return res;
}

Poly mult(const Poly& a, const Poly& b) {
	Poly res((int)a.size() + b.size() - 1);
	for (int i = 0; i < (int)a.size(); ++i) {
		for (int j = 0; j < (int)b.size(); ++j) {
			res[i + j] += a[i] * b[j];
		}
	}
	return res;
}

Poly subst(const Poly& p, const Poly& q) {
	Poly res;
	Poly cur = {1};
	for (auto c : p) {
		auto tmp = cur;
		for (auto& x : tmp) {
			x *= c;
		}
		res = add(res, tmp);
		cur = mult(cur, q);
	}
	return res;
}

Fraction apply_poly(const Poly& p, Fraction x) {
	Fraction res = 0;
	for (int i = (int)p.size() - 1; i >= 0; --i) {
		res = res * x + p[i];
	}
	return res;
}

Poly norm_to_bin(Poly p) {
	Poly res(p.size());
	vector<Poly> bins = {{1}};
	for (int i = 0; i < (int)p.size() - 1; ++i) {
		auto q = mult(bins.back(), {i, 1});
		bins.push_back(q);
	}
	for (int i = (int)p.size() - 1; i >= 0; --i) {
		auto c = p[i];
		res[i] = c;
		auto tmp = bins[i];
		for (auto& x : tmp) {
			x *= c;
		}
		p = sub(p, tmp);
	}
	return res;
}

Poly lift(Poly p) {
	p.insert(p.begin(), 0);
	for (int i = 1; i < (int)p.size(); ++i) {
		p[i] /= i;
	}
	return p;
}

Poly bin_to_norm(const Poly& p) {
	Poly res;
	Poly q = {1};
	for (int i = 0; i < (int)p.size(); ++i) {
		auto tmp = q;
		for (auto& x : tmp) {
			x *= p[i];
		}
		res = add(res, tmp);
		q = mult(q, {i, 1});
	}
	return res;
}

Poly _poly_to_sum(const Poly& p) {
	return bin_to_norm(lift(norm_to_bin(p)));
}

const int N = 184'000;
const int D = 17;
vector<Poly> pss = []() {
	vector<Poly> res(D);
	for (int i = 0; i < D; ++i) {
		res[i].resize(i + 1);
		res[i].back() = 1;
		res[i] = _poly_to_sum(res[i]);
	}
	return res;
}();

Poly poly_to_sum(const Poly& p) {
	Poly res;
	for (int i = 0; i < (int)p.size(); ++i) {
		auto tmp = pss[i];
		for (auto& x : tmp) {
			x *= p[i];
		}
		res = add(res, tmp);
	}
	return res;
}

Fraction sumpoly(const Poly& p, const Fraction& x) {
	return apply_poly(poly_to_sum(p), x);
}

BigInteger isqrt(BigInteger n) {
	if (n <= 1) {
		return n;
	}
	BigInteger x = n / 2;
	BigInteger y = (x + n / x) / 2;
	while (y < x) {
		x = y;
		y = (x + n / x) / 2;
	}
	return x;
}

BigInteger S(BigInteger n) {
	return (n + 1) * (n + 2) / 2 - 1;
}

BigInteger P(BigInteger n) {
	auto k = (isqrt(n * 8 + 9) - 3) / 2;
	while (S(k) < n) {
		k += 1;
	}
	return k;
}

Fraction Q[N];
Fraction prefQ[D][N];

Fraction find_Q(BigInteger n);

Fraction f(BigInteger n, Poly p) {
	if (n < N) {
		auto nn = n.to_int();
		Fraction ans = 0;
		for (int i = 0; i < (int)p.size(); ++i) {
			ans += prefQ[i][nn] * p[i];
		}
		return ans;
	}

	auto mx = P(n);
	auto fr = S(mx - 1) + 1;
	p = poly_to_sum(p);
	auto q = subst(p, {-1, 1});
	for (auto& x : q) {
		x = -x;
	}
	q[0] += apply_poly(p, n);
	q = poly_to_sum(q);

	auto ans = find_Q(mx) * (apply_poly(q, n) - apply_poly(q, fr - 1));
	q = sub(subst(q, {0, Fraction(3, 2), Fraction(1, 2)}), subst(q, {-1, Fraction(1, 2), Fraction(1, 2)}));
	ans += f(mx - 1, q);

	return ans;
}

Fraction find_Q(BigInteger n) {
	if (n < N) {
		return Q[n.to_int()];
	}

	auto mx = P(n);
	return f(mx, {1, 1}) - find_Q(mx) * (S(mx) - n);
}

void solve() {
	BigInteger n;
	cin >> n;
	cout << find_Q(n) << "\n";
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	Q[1] = 1;
	for (int i = 0; i < D; ++i) {
		prefQ[i][1] = 1;
	}
	for (int i = 2; i < N; ++i) {
		Q[i] = Q[i - 1] + Q[P(i).to_int()];
		auto cur = Q[i];
		for (int j = 0; j < D; ++j) {
			prefQ[j][i] = prefQ[j][i - 1] + cur;
			cur *= i;
		}
	}

	int t = nxt();
	while (t--) {
		solve();
	}

	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2372ms
memory: 261892kb

input:

4
10
100
1000
987654321123456789

output:

30
2522
244274
235139898689017607381017686096176798

result:

ok 4 lines

Test #2:

score: 0
Accepted
time: 3115ms
memory: 261840kb

input:

10000
613939207402503646
408978283345333197
976677512231308716
629053280913850466
148712339
236220313279945487
590396556995977994
9226
215693877607285701
649702683896705
343173887453826567
847003949499596615
867133040287550291
159928123569892354
864534948175618654
209739383170746721
4295456752378791...

output:

91030728117067063595428375419346402
40469246710473908695676971059074376
229951682342450470520349294486964970
95558039501640054006660579352994194
5418340556433412
13536357243714243974772906966693552
84197207203086091733385317631619504
20934656
11291075621624104092841708040651034
104019777231815308683...

result:

ok 10000 lines

Test #3:

score: 0
Accepted
time: 2792ms
memory: 261852kb

input:

1000
6403632579734162001008235137760132245297
1307698664787972023762442022139627469666
668870338048562416595095770565441759482
5092270
8806864498496723812760785099973409980711
2178464116010775202899984038946879469187
204381824371
8638495456004772442511643693521120926431
45954412333082528168092594892...

output:

9822905445826021159291522774438593145331066315784567505849706373529921001845336
409552844852728078841401625660602682494169687360338453221088647649526339235330
107160056181509722327918304399871120167096186888511567354513496578559803370274
6354453295964
185817323129718525790559571287806776421589155460...

result:

ok 1000 lines

Test #4:

score: 0
Accepted
time: 3285ms
memory: 261916kb

input:

2000
2587627816607030340103003175959756184662
7728753705064569253253827797978613582938
6507847628603052973674714721
6989857636824717968431061258300652290539
4734281027640913533293237760425416005062
9411123735455625690768098631226366597446
8309753930995253536640660321476246470149
63565157427098067709...

output:

1603610451790269237852635641930301658193367441164307312552842461667027137613454
14309943493171496191506053530749878345271155973702143153225815632926701434642842
10414697803791950572309383355053080338229465674803757518
11704102206894264239190418551798088411458157423624785417336589284698838535371266
5...

result:

ok 2000 lines

Test #5:

score: 0
Accepted
time: 4940ms
memory: 261848kb

input:

5000
6701025283447923273597553918313900029215
1618190467906965189844764312914748628527
2135261797018456059451326428589353332126
8027429917075086154217136768450383650445
8263301530632040969183919589286944799002
376886964626613356031779878
1191561726595055348898524031899625958102
453561433135467095374...

output:

10756647971303093856509780939435968749671842310025383400207261624750784751725876
627115945498078452730193858129037650151913122482133071938783012929533045529940
1091921493223233296724616654299408127388059493196845968361252389122720100379070
154375707400033063668088306493199269136326791073281723548116...

result:

ok 5000 lines

Test #6:

score: 0
Accepted
time: 7582ms
memory: 261904kb

input:

10000
260865660295317278841
5232352637620496342310336202478387251106
7108789244285764135987032973912918380
12766535319519586095540974948550152061
5138306300154916887884637635208203681949
7603163140266839847784708214115317398585
149590294591155205497765668766786424787
63283557694500045989299147454323...

output:

16323111740957704392106241109891718054228
6557703685144914472554701877112177422100848067214049191882271294010013621817762
12143115079716078114619105501427985631361994195400195527663921137836417758
39139456824156526604158618001888125076786817219954316014947704612553450312
6324051018379978443719363340...

result:

ok 10000 lines