# bzoj3122 [SDOI2013]随机数生成器

bzoj3122 [SDOI2013]随机数生成器

$0\leq a,\ b,\ t,\ P\leq10^9,\ P$ 为质数

BSGS

$X_k=a^{k-1}x+b\displaystyle\sum_{i=0}^{k-2}a_i$

\begin{aligned}\displaystyle\sum_{i=0}^{k-2}a_i&\equiv\frac{t-a^{k-1}x}{b}\pmod P\\\frac{a^{k-1}-1}{a-1}&\equiv\frac{t-a^{k-1}x}{b}\pmod P\\a^{k-1}(b-x+ax)&\equiv at-t+b\pmod P\\a^{k-1}&\equiv\frac{at-t+b}{b-x+ax}\pmod P\end{aligned}

• $x=t:ans=1$
• $a=1$
• $b=0:ans=-1$
• $b\neq0:ans=\frac{t-x}{b}+1$
• $a=0$
• $b=t:ans=2$
• $b\neq t:ans=-1$

#include <bits/stdc++.h>
using namespace std;

int P;

int qp(int a, int k) {
int res = bool(a);
for (; k; k >>= 1, a = 1ll * a * a % P) {
if (k & 1) res = 1ll * res * a % P;
}
return res % P;
}

int bsgs(int a, int b) {
if (!a && b) return -1;
map <int, int> s;
int sz = sqrt(P), inv_a = qp(a, P - 2), pw = qp(a, sz), cur = 1;
for (int i = 0; i <= sz; i++) {
s.insert(make_pair(1ll * b * cur % P, i)), cur = 1ll * cur * inv_a % P;
}
cur = 1;
map <int, int> :: iterator it;
for (int i = 0; i <= sz; i++, cur = 1ll * cur * pw % P) {
if ((it = s.find(cur)) != s.end()) {
return i * sz + (it -> second);
}
}
return -1;
}

int main() {
int Tests, a, b, x, t, A, B;
scanf("%d", &Tests);
while (Tests--) {
scanf("%d %d %d %d %d", &P, &a, &b, &x, &t);
a %= P, b %= P, x %= P, t %= P;
if (x == t) {
puts("1"); continue;
} else if (a == 1) {
if (!b) {
puts("-1"); continue;
}
printf("%d\n", 1ll * (t - x + P) * qp(b, P - 2) % P + 1);
continue;
} else if (!a) {
puts(b == t ? "2" : "-1");
continue;
}
A = a, B = 1ll * (1ll * a * t - t + b + P) % P * qp((b - x + 1ll * a * x + P) % P, P - 2) % P;
int ans = bsgs(A, B);
printf("%d\n", ~ans ? ans + 1 : ans);
}
return 0;
}
posted @ 2019-04-05 17:05  cnJuanzhang  阅读(160)  评论(0编辑  收藏  举报