#include <vector>
#include <tuple>
#include <chrono>
#include <iostream>
#include <inttypes.h>
using namespace std;
typedef unsigned int uint;
static vector<uint16_t> sieve;
static uint64_t fcnt;
void genSieve(uint n, vector<uint16_t> &sieve)
{
sieve.clear();
uint ye = (n + 1) / 2;
sieve.resize(ye, 0);
for (uint x = 1; ; x++) {
if (sieve[x] != 0)
continue;
uint p = x + x + 1, yb = (x + x) * (x + 1);
if (yb >= ye)
break;
for (uint y = yb; y < ye; y += p)
sieve[y] = x;
}
}
static void factorize(uint n, vector<tuple<uint, uint>> &result)
{
result.clear();
if (n % 2 == 0) {
uint count = 0;
do {
n /= 2;
count++;
} while (n % 2 == 0);
result.push_back(make_tuple(2, count));
}
for (;;) {
uint p = sieve[n / 2];
if (p == 0)
break;
p = p + p + 1;
uint count = 0;
do {
n /= p;
count++;
} while (n % p == 0);
result.push_back(make_tuple(p, count));
}
if (n > 1)
result.push_back(make_tuple(n, 1));
}
static uint factorial_power(uint m, uint p)
{
uint result = 0;
while (m >= p) {
m /= p;
result += m;
}
return result;
}
static uint value(uint p, uint k)
{
if (k <= p)
return k * p;
uint res = k - (k - 1) / p;
uint resv = res + factorial_power(res, p);
while (resv < k) {
fcnt++;
res++;
resv++;
for (uint x = res; x % p == 0; x /= p)
resv++;
}
return res * p;
}
uint s(uint n)
{
vector<tuple<uint, uint>> factors;
factorize(n, factors);
//return factors.size();
uint res = 1;
for (auto v: factors) {
uint p, k;
tie(p, k) = v;
#if 1
uint r = value(p, k);
if (res < r)
res = r;
#else
uint resv = factorial_power(res, p);
if (resv < k)
res = value(p, k);
#endif
}
return res;
}
int main()
{
auto t1 = chrono::high_resolution_clock::now();
constexpr int m = 23000000;
constexpr int n = 24000000;
genSieve(n, sieve);
uint64_t result = 0;
fcnt = 0;
#if 1
for (auto i = m; i <= n; ++i)
result += s(i);
#endif
auto t2 = chrono::high_resolution_clock::now();
cout << result << endl;
cout << fcnt << endl;
cout << "time: " << chrono::duration_cast<chrono::microseconds>(t2 - t1).count() << "us" << endl;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxpbnR0eXBlcy5oPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdHlwZWRlZiB1bnNpZ25lZCBpbnQgdWludDsKCnN0YXRpYyB2ZWN0b3I8dWludDE2X3Q+IHNpZXZlOwpzdGF0aWMgdWludDY0X3QgZmNudDsKCnZvaWQgZ2VuU2lldmUodWludCBuLCB2ZWN0b3I8dWludDE2X3Q+ICZzaWV2ZSkKewoJc2lldmUuY2xlYXIoKTsKCXVpbnQgeWUgPSAobiArIDEpIC8gMjsKCXNpZXZlLnJlc2l6ZSh5ZSwgMCk7Cglmb3IgKHVpbnQgeCA9IDE7IDsgeCsrKSB7CgkJaWYgKHNpZXZlW3hdICE9IDApCgkJCWNvbnRpbnVlOwoJCXVpbnQgcCA9IHggKyB4ICsgMSwgeWIgPSAoeCArIHgpICogKHggKyAxKTsKCQlpZiAoeWIgPj0geWUpCgkJCWJyZWFrOwoJCWZvciAodWludCB5ID0geWI7IHkgPCB5ZTsgeSArPSBwKQoJCQlzaWV2ZVt5XSA9IHg7Cgl9Cn0KCnN0YXRpYyB2b2lkIGZhY3Rvcml6ZSh1aW50IG4sICB2ZWN0b3I8dHVwbGU8dWludCwgdWludD4+ICZyZXN1bHQpCiB7CglyZXN1bHQuY2xlYXIoKTsKCWlmIChuICUgMiA9PSAwKSB7CgkJdWludCBjb3VudCA9IDA7CgkJZG8gewoJCQluIC89IDI7CgkJCWNvdW50Kys7CgkJfSB3aGlsZSAobiAlIDIgPT0gMCk7CgkJcmVzdWx0LnB1c2hfYmFjayhtYWtlX3R1cGxlKDIsIGNvdW50KSk7Cgl9CgoJZm9yICg7OykgewoJCXVpbnQgcCA9IHNpZXZlW24gLyAyXTsKCQlpZiAocCA9PSAwKQoJCQlicmVhazsKCQlwID0gcCArIHAgKyAxOwoJCXVpbnQgY291bnQgPSAwOwoJCWRvIHsKCQkJbiAvPSBwOwoJCQljb3VudCsrOwoJCX0gd2hpbGUgKG4gJSBwID09IDApOwoJCXJlc3VsdC5wdXNoX2JhY2sobWFrZV90dXBsZShwLCBjb3VudCkpOwoJfQoJaWYgKG4gPiAxKQoJCXJlc3VsdC5wdXNoX2JhY2sobWFrZV90dXBsZShuLCAxKSk7Cn0KCgpzdGF0aWMgdWludCBmYWN0b3JpYWxfcG93ZXIodWludCBtLCB1aW50IHApCnsKCXVpbnQgcmVzdWx0ID0gMDsKCXdoaWxlIChtID49IHApIHsKCQltIC89IHA7CiAgICAgICAgcmVzdWx0ICs9IG07Cgl9CglyZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgdWludCB2YWx1ZSh1aW50IHAsIHVpbnQgaykKewoJaWYgKGsgPD0gcCkKCQlyZXR1cm4gayAqIHA7Cgl1aW50IHJlcyA9IGsgLSAoayAtIDEpIC8gcDsKCXVpbnQgcmVzdiA9IHJlcyArIGZhY3RvcmlhbF9wb3dlcihyZXMsIHApOwkKCXdoaWxlIChyZXN2IDwgaykgewoJCWZjbnQrKzsKCQlyZXMrKzsKCQlyZXN2Kys7CgkJZm9yICh1aW50IHggPSByZXM7IHggJSBwID09IDA7IHggLz0gcCkKCQkJcmVzdisrOwoJfQoKCXJldHVybiByZXMgKiBwOwp9CgoKdWludCBzKHVpbnQgbikKewoJdmVjdG9yPHR1cGxlPHVpbnQsIHVpbnQ+PiBmYWN0b3JzOwoJZmFjdG9yaXplKG4sIGZhY3RvcnMpOwovL3JldHVybiBmYWN0b3JzLnNpemUoKTsKICAgIHVpbnQgcmVzID0gMTsKICAgIGZvciAoYXV0byB2OiBmYWN0b3JzKSB7CiAgICAgICAgdWludCBwLCBrOwogICAgICAgIHRpZShwLCBrKSA9IHY7CiNpZiAxCgkJdWludCByID0gdmFsdWUocCwgayk7CgkJaWYgKHJlcyA8IHIpCgkJCXJlcyA9IHI7CiNlbHNlCiAgICAgICAgdWludCByZXN2ID0gZmFjdG9yaWFsX3Bvd2VyKHJlcywgcCk7CiAgICAgICAgaWYgKHJlc3YgPCBrKQoJCQlyZXMgPSB2YWx1ZShwLCBrKTsKI2VuZGlmCgl9CglyZXR1cm4gcmVzOwp9CgppbnQgbWFpbigpCnsKICAgIGF1dG8gdDEgPSBjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CiAgICBjb25zdGV4cHIgaW50IG0gPSAyMzAwMDAwMDsKICAgIGNvbnN0ZXhwciBpbnQgbiA9IDI0MDAwMDAwOwoJZ2VuU2lldmUobiwgc2lldmUpOwogICAgdWludDY0X3QgcmVzdWx0ID0gMDsKICAgIGZjbnQgPSAwOwojaWYgMQogICAgZm9yIChhdXRvIGkgPSBtOyBpIDw9IG47ICsraSkKICAgICAgICByZXN1bHQgKz0gcyhpKTsKI2VuZGlmCiAgICBhdXRvIHQyID0gY2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOwoJY291dCA8PCByZXN1bHQgPDwgZW5kbDsKCWNvdXQgPDwgZmNudCA8PCBlbmRsOwoJY291dCA8PCAidGltZTogIiA8PCBjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8Y2hyb25vOjptaWNyb3NlY29uZHM+KHQyIC0gdDEpLmNvdW50KCkgPDwgInVzIiA8PCBlbmRsOwp9Cgo=