#include <iostream>
#include <cstdint>
template<class T>
T mod(T a, T b)
{
a %= b;
return a>0?a:a+b;
}
void ext_euclid(int64_t a, int64_t b, int64_t *lastx, int64_t *lasty)
{
int64_t x = 0;
int64_t y = 1;
*lastx = 1;
*lasty = 0;
int64_t q, r;
int64_t tmp;
while (b != 0)
{
q = a / b;
r = a % b;
tmp = x; x = *lastx - q * x; *lastx = tmp;
tmp = y; y = *lasty - q * y; *lasty = tmp;
a = b; b = r;
}
}
class ReversibleLCG {
int64_t x;
int64_t a;
int64_t m;
int64_t c;
int64_t ainverse;
public:
ReversibleLCG(int seed) : x(seed), a(1103515245), m(1u<<31u), c(12345)
{
int64_t x, q;
ext_euclid(a, m, &x, &q);
ainverse = mod(x, int64_t(m));
}
unsigned int next()
{
return x = (a*x + c) % m;
}
unsigned int prev()
{
return x= (ainverse*mod(x - c, m)) % m;
}
};
int main()
{
ReversibleLCG rng(0);
unsigned int prev = rng.next();
for(int i = 1;i<10;++i)
{
ReversibleLCG rng(i);
unsigned int cur = rng.next();
std::cout << cur-prev << std::endl;
prev = cur;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGludD4KCnRlbXBsYXRlPGNsYXNzIFQ+ClQgbW9kKFQgYSwgVCBiKQp7CiAgICBhICU9IGI7CiAgICByZXR1cm4gYT4wP2E6YStiOwp9CiAKdm9pZCBleHRfZXVjbGlkKGludDY0X3QgYSwgaW50NjRfdCBiLCBpbnQ2NF90ICpsYXN0eCwgaW50NjRfdCAqbGFzdHkpCnsKICAgIGludDY0X3QgeCA9IDA7CiAgICBpbnQ2NF90IHkgPSAxOwogICAgKmxhc3R4ID0gMTsKICAgICpsYXN0eSA9IDA7CiAgICBpbnQ2NF90IHEsIHI7CiAgICBpbnQ2NF90IHRtcDsKICAgIAogICAgd2hpbGUgKGIgIT0gMCkKICAgIHsKICAgICAgICBxID0gYSAvIGI7CiAgICAgICAgciA9IGEgJSBiOwogICAgICAgIHRtcCA9IHg7IHggPSAqbGFzdHggLSBxICogeDsgKmxhc3R4ID0gdG1wOwogICAgICAgIHRtcCA9IHk7IHkgPSAqbGFzdHkgLSBxICogeTsgKmxhc3R5ID0gdG1wOwogICAgICAgIGEgPSBiOyBiID0gcjsKICAgIH0KfQoKY2xhc3MgUmV2ZXJzaWJsZUxDRyB7CiAgICBpbnQ2NF90IHg7CiAgICBpbnQ2NF90IGE7CiAgICBpbnQ2NF90IG07CiAgICBpbnQ2NF90IGM7CiAgICBpbnQ2NF90IGFpbnZlcnNlOwpwdWJsaWM6CiAgICBSZXZlcnNpYmxlTENHKGludCBzZWVkKSA6IHgoc2VlZCksIGEoMTEwMzUxNTI0NSksIG0oMXU8PDMxdSksIGMoMTIzNDUpCiAgICB7CiAgICAgICAgaW50NjRfdCB4LCBxOwogICAgICAgIGV4dF9ldWNsaWQoYSwgbSwgJngsICZxKTsKICAgICAgICBhaW52ZXJzZSA9ICBtb2QoeCwgaW50NjRfdChtKSk7CiAgICB9CiAgICB1bnNpZ25lZCBpbnQgbmV4dCgpCiAgICB7CiAgICAgICAgcmV0dXJuIHggPSAoYSp4ICsgYykgJSBtOwogICAgfSAgICAKICAgIHVuc2lnbmVkIGludCBwcmV2KCkKICAgIHsKICAgICAgICByZXR1cm4geD0gKGFpbnZlcnNlKm1vZCh4IC0gYywgbSkpICUgbTsKICAgIH0gCn07CgppbnQgbWFpbigpCnsKICAgIFJldmVyc2libGVMQ0cgcm5nKDApOwogICAgdW5zaWduZWQgaW50IHByZXYgPSBybmcubmV4dCgpOwogICAgZm9yKGludCBpID0gMTtpPDEwOysraSkKICAgIHsKICAgICAgICBSZXZlcnNpYmxlTENHIHJuZyhpKTsKICAgICAgICB1bnNpZ25lZCBpbnQgY3VyID0gcm5nLm5leHQoKTsKICAgICAgICBzdGQ6OmNvdXQgPDwgY3VyLXByZXYgPDwgc3RkOjplbmRsOwogICAgICAgIHByZXYgPSBjdXI7CiAgICB9Cn0=