[BZOJ2875][Noi2012]隨機數生成器[等比數列求和+取模]
阿新 • • 發佈:2018-12-28
其實主要程式碼就是這個。。。
ull Sum(ull n,ull t) {//n是長度 t是首項 m是公比
if (n == 1) return t;
ull ret = Sum(n/2, t);
ret = (ret + mul(ret, Pow(m, n/2))) % mod;
if (n & 1) ret = (ret + mul(Pow(m, (n-1)), t))%mod;
return ret;
}
\(x[1] = (ax[0] + c) \pmod m\)
\(x[2] = a((ax[0] + c)+c) = a^2x[0] + ac + c \pmod m\)
\(x[3] = a(a^2x[0] + ac + c)+c = a^3x[0] + a^2c + ac + c \pmod m\)
\(x[i]\)的第一項是\(a^ix[0]\) 後面是一個首項為\(c\) 公比為\(a\)的等比數列
#include <bits/stdc++.h> typedef unsigned long long ull; using namespace std; ull mod, a, c, x, n, g, mod1, m; ull ret, ans; inline ull mul(ull x,ull y) {//龜速乘法 for(ret = 0; y; y >>= 1) { if (y & 1) ret = (ret + x) % mod; x = (x + x) % mod; } return ret; } ull Pow(ull a,ull k) {//快速冪 ull x = a; for(ans = 1; k; k >>= 1) { if (k & 1) ans = mul(ans, x); x = mul(x, x); } return ans; } ull Sum(ull n,ull t) {//n是長度 t是首項 m是公比 if (n == 1) return t; ull ret = Sum(n/2, t); ret = (ret + mul(ret, Pow(m, n/2))) % mod; if (n & 1) ret = (ret + mul(Pow(m, (n-1)), t))%mod; return ret; } int main() { cin >> mod >> m >> c >> x >> n >> mod1; ull ans = Pow(m, n); ans = mul(ans, x); ans = (ans + Sum(n, c)) % mod; cout << ans % mod1; return 0; }