BSGS,式子推对了,但是重改了无数次也没写出来……
#include<iostream>
#include<unordered_map>
#include<cmath>
using namespace std;
#define int long long
int gcd(int a, int b) { return (b == 0? a : gcd(b, a%b)); }
int quickpow(int a, int x, int p)
{
int sum = 1, tot = a;
while(x)
{
if(x & 1)
sum = (sum * tot) % p;
tot = (tot * tot) % p;
x >>= 1;
}
return sum;
}
int inv(int k, int p)
{
return quickpow(k, p - 2, p);
}
int BSGS(int a, int b, int p)
{
a %= p, b %= p;
if(b == 1)
return 0;
unordered_map <int, int> hash;
int am = 1, ami = 1, baj = b;
int M = ceil(sqrt(p));
for(int j = 0; j < M; j ++)
hash[baj] = j, baj = (baj * a) % p;
am = quickpow(a, M, p);
for(int i = 1; i <= M; i ++)
{
ami = (ami * am) % p;
if(hash.count(ami))
return i * M - hash[ami];
}
return -1;
}
signed main()
{
int T;
cin >> T;
while(T --)
{
int p, a, b, x1, t;
cin >> p >> a >> b >> x1 >> t;
if(x1 == t)
{
cout << "1\n";
continue;
}
if(a == 0)
{
cout << (b == t? 2:-1) << '\n';
continue;
}
if(a == 1)
{
int w = ((t-x1) % p + p) % p;
if(w % gcd(b, p) != 0)
{
cout << "-1\n";
continue;
}
int inv_b = inv(b, p);
cout << ( ((t-x1) * inv_b)%p + p )%p + 1 << '\n';
}
int inv_a_1, inv_fm, y, ans;
inv_a_1 = inv(a-1, p);
inv_fm = inv((x1 + (b*inv_a_1)%p) % p, p);
ans = BSGS(a, ( ( (t + (b*inv_a_1)%p)%p ) * (inv_fm%p) )% p, p);
cout << (ans == -1? ans : ans+1) << '\n';
}
return 0;
}