題意:給出 瓤摧,已知序列 滿足 竿裂,再給出Q組詢問(wèn)每次一個(gè)數(shù) ,求最小的index使得 , 不存在則輸出-1
題解:令, 于是有, 于是yi就成了一個(gè)等比數(shù)列照弥。這樣我們就發(fā)現(xiàn)本題適用于BSGS算法腻异。注意到傳統(tǒng)的BSGS算法都是分成 的兩個(gè)部分,但是由于這個(gè)題的Q非常大产喉,于是我們可以預(yù)處理(即baby-step部分)更多的項(xiàng):例如捂掰, 。最后特判一下a=0和a=1的情況曾沈,這個(gè)題就做完了。
一些玄學(xué)的情況:這份代碼ac過(guò)(雖然時(shí)間有點(diǎn)勉強(qiáng))鸥昏,但是后來(lái)交是tle的塞俱,再等一會(huì)又能ac了(牛客的測(cè)評(píng)機(jī)啊吏垮。障涯。罐旗。。)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <vector>
#define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i)
using namespace std;
using ll = long long;
const ll maxn = 1e6;
ll mod;
ll bin(ll x, ll n, ll MOD)
{
ll ret = MOD != 1;
for (x %= MOD; n; n >>= 1, x = x * x % MOD)
if (n & 1)
ret = ret * x % MOD;
return ret;
}
inline ll get_inv(ll x, ll p) { return bin(x, p - 2, p); }
unordered_map<ll, ll> mp;
ll m, ma;
ll init(ll a, ll p)
{
mp.clear();
ll v = 1;
m = pow(p + 1.5, 2.0 / 3.0);
ma = pow(p + 1.5, 1.0 / 3.0) + 3;
FOR(i, 1, m + 1)
{
v = v * a % p;
mp[v] = i;
}
return v;
}
ll BSGS(ll a, ll b, ll p, ll init_d)
{ // a^x = b (mod p)
a %= p;
if (!a && !b)
return 1;
if (!a)
return -1;
ll v = init_d;
ll vv = init_d;
ll inv_b = get_inv(b, p);
FOR(i, 1, ma + 1)
{
auto it = mp.find(vv * inv_b % p);
if (it != mp.end())
return i * m - it->second;
vv = vv * v % p;
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
int round;
cin >> round;
while (round--)
{
ll n, x0, a, b, p;
int Q;
cin >> n >> x0 >> a >> b >> p;
cin >> Q;
if (a == 0)
{
while (Q--)
{
ll v;
cin >> v;
if (v == x0)
{
cout << 0 << endl;
}
else if (v == b)
{
cout << 1 << endl;
}
else
{
cout << -1 << endl;
}
}
}
else if (a == 1)
{
ll invb = get_inv(b, p);
while (Q--)
{
ll v;
cin >> v;
ll ans = (((v - x0 + p) % p) * invb) % p;
if (ans >= n)
{
cout << -1 << endl;
}
else
{
cout << ans << endl;
}
}
}
else
{
ll bais = b * get_inv(a - 1, p) % p;
ll y0 = (x0 + bais) % p;
ll inv_y0 = get_inv(y0, p);
// m = min(maxn, n);
// ma = p / maxn + 3;
ll init_d = init(a, p);
while (Q--)
{
ll v;
cin >> v;
v = (v + bais) % p;
v = (v * inv_y0) % p;
ll res = BSGS(a, v, p, init_d);
if (res >= n)
res = -1;
cout << res << endl;
}
}
}
}