题解 P3306 【[SDOI2013]随机数生成器】
个人博客
欢迎大佬互换友链
Link
洛谷 3306
Solution
大力推式子
那么我们得到
也就是我们要判断如下方程是否有整数解,若有则求解
继续化化化
大功告成,用BSGS求解出
Detail 1
对于
Detail 2
对于
Detail 3
对于
Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
using std::cin;
using std::cout;
using std::endl;
template <typename I>
inline void read(I& x)
{
char c = getchar();
for (; !isdigit(c); c = getchar());
for (x = 0; isdigit(c); x = x * 10 + (c ^ 48), c = getchar());
}
long long NUMOFCASES, a, b, p, x, t, X, Y;
long long exp(long long b, int i, int p)
{
long long r = 1;
for (; i; i >>= 1, b = b * b % p)
if (i & 1)
r = r * b % p;
return r;
}
long long gcd(long long a, long long b)
{
return b ? gcd(b, a % b) : a;
}
long long inv(long long x, int MOD)
{
return exp(x, MOD - 2, MOD);
}
long long bsgs(long long a, long long b, int MOD)
{
a %= MOD, b %= MOD;
std::map <long long, long long> map;
register long long m = ceil(sqrt(MOD)), t = 1;
for (register int i = 0; i < m; ++i)
{
if (!map.count(t))
map[t] = i;
t = t * a % MOD;
}
register long long k = inv(t, MOD), w = b;
for (int i = 0; i < m; ++i)
{
if (map.count(w))
return i * m + map[w];
w = w * k % MOD;
}
return -1;
}
int main()
{
read(NUMOFCASES);
for (; NUMOFCASES; --NUMOFCASES)
{
read(p), read(a), read(b), read(x), read(t);
if (x == t)
cout << 1 << endl;
else if (a == 1)
{
t = ((t - x) % p + p) % p;
if (t % gcd(b, p))
cout << -1 << endl;
else
{
if ((t * inv(b, p) + 1) % p == 0)
cout << p << endl;
else
cout << (t * inv(b, p) + 1) % p << endl;
}
}
else if (a == 0)
{
if (b == t)
cout << 2 << endl;
else
cout << -1 << endl;
}
else
{
long long ans = bsgs(a, ((t - b * inv(1 - a, p)) % p + p) % p * inv(((x - b * inv(1 - a, p)) % p + p) % p, p), p) % p;
if (ans == -1)
cout << -1 << endl;
else
cout << ans + 1 << endl;
}
}
}