intgcd(int a, int b){ if (!b) return a; returngcd(b, a % b); }
intexgcd(int a, int b, int& x, int& y){ if (!b) return x = 1, y = 0, a; int d = exgcd(b, a % b, y, x); return y -= a / b * x, d; }
intinv(int a, int p){ int res, k, mo, d = exgcd(a, p, res, k); mo = p / d; res %= mo; if (res < 0) res += mo; return res; }
map<int, int> mp;
intBSGS(int a, int b, int p){ mp.clear(); int m = sqrt(p) + 1, aj = a; for (int j = 1; j <= m; j++) { mp[b * aj % p] = j; if (j != m) aj = aj * a % p; } int ai = aj; for (int i = 1; i <= m; i++, ai = ai * aj % p) if (mp.count(ai)) return i * m - mp[ai]; return-1; }
intexBSGS(int a, int b, int p){ a %= p, b %= p; if (p == 1 || b == 1) return0;
int d = gcd(a, p); if (d == 1) returnBSGS(a, b, p); if (b % d) return-1; int res = exBSGS(a, b / d * inv(a / d, p / d), p / d); if (res == -1) return-1; return res + 1; }
signedmain(){ int a, p, b; while (read(a, p, b), a || p || b) { int x = exBSGS(a, b, p); if (x == -1) write("No Solution"); elsewrite(x); } return0; }
#define int long long typedefunsignedlonglong ull; int p; char s[30000010];
structMatrix { int dat[2][2];
Matrix() { memset(dat, 0, sizeof dat); }
ull hash(){ ull res = 0; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) res = res * p + dat[i][j]; return res; }
Matrix operator*(const Matrix& mat) { Matrix res; for (int i = 0; i < 2; i++) for (int k = 0; k < 2; k++) for (int j = 0; j < 2; j++) res.dat[i][j] = (res.dat[i][j] + dat[i][k] * mat.dat[k][j]) % p; return res; } } A, E;
map<ull, int> mp;
Matrix qmi(Matrix a, int k){ Matrix res = E; while (k) { if (k & 1) res = res * a; a = a * a; k >>= 1; } return res; }
intBSGS(){ int m = sqrt(6*p) + 1; Matrix Aj = E; for (int j = 0; j < m; j++, Aj = Aj * A) mp[Aj.hash()] = j; Matrix Ai = Aj; for (int i = 1; i <= m; i++, Ai = Ai * Aj) if (mp.count(Ai.hash())) return i * m - mp[Ai.hash()]; assert(false); }
signedmain(){ A.dat[0][0] = A.dat[0][1] = A.dat[1][0] = 1; E.dat[0][0] = E.dat[1][1] = 1; scanf("%s%lld", s, &p); int x = BSGS(), n = 0; for (int i = 0; s[i]; i++) n = (n * 10 + s[i] - '0') % x; return !printf("%lld\n", qmi(A, n).dat[0][1]); }
[SDOI2013] 随机数生成器
共 T 组测试数据,给定 p,a,b,x1,t 其中数列 xi 满足递推式:xi+1≡axi+b(modp),问 i 最小为多少使得 xi=t 或报告无解。
constint N = 100000010; int primes[N/10], cnt; bitset<N> st; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
intrd(int l, int r){ returnuniform_int_distribution<int>(l, r)(rng); }
voidinit(int n){ for (int i = 2; i <= n; i++) { if (!st[i]) primes[++cnt] = i; for (int j = 1; i <= n/primes[j]; j++) { st[i*primes[j]] = 1; if (i % primes[j] == 0) break; } } }
intcalc(int a, int b, int x1, int p){ staticint st[N], ts; st[x1] = ++ts; int ans = 0; while (1) { int nxt = (1ll * a * x1 + b) % p; if (st[nxt] == ts) return ans; st[x1 = nxt] = ts, ans++; } assert(false); }
intmain(){ int n = N-1; init(n); for (int i = 1; i <= 10; i++) { int k = rd(1, cnt); int p = primes[k]; int a = rd(0, p-1), b = rd(0, p-1), x1 = rd(0, p-1); printf("%d: %d,\n", p, calc(a, b, x1, p)); } return0; }
intqmi(int a, int k, int p){ int res = 1; while (k) { if (k & 1) res = res * a % p; a = a * a % p; k >>= 1; } return res; }
intBSGS(){ mp.clear(); int m = sqrt(p) * 2, inva = qmi(a, p-2, p); Matrix A; A.dat[0][0] = inva, A.dat[0][1] = -b * inva % p + p, A.dat[1][1] = 1; int x0 = A.mul(x1); Matrix Aj = E; for (int j = 0; j < m; j++, Aj = Aj * A) mp[Aj.mul(x0)] = j; Matrix Ai = Aj; for (int i = 1; i <= m; i++, Ai = Ai * Aj) { int x = Ai.mul(t); if (mp.count(x)) return i * m - mp[x]; } return-1; }
intsolve(){ if (a) returnBSGS(); if (t == x1) return1; if (t == b) return2; return-1; }
signedmain(){ E.dat[0][0] = E.dat[1][1] = 1; read(T); while (T--) { read(p, a, b, x1, t); write(solve()); } return0; }