思路就是找规律发现递推公式,用递推公式求解通项公式,bsgs分奇偶求解可以看这篇博客https://www.cnblogs.com/xiaopangpangdehome/p/15042792.html
(有exbsgs和bsgs模板)
有一道类似的题:
随机数生成器(洛谷也有这个题目)
题目大意:
思路:利用特征方程求解通项公式,再用bsgs求解,时间复杂度是O(sqrt§),注意一些特殊情况。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+7;
const int mod=998244353;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll hs[N], head[N], nexts[N], id[N], top;
void insert(ll x, ll y, ll mod) //mod传 N
{
ll k = x % mod;
hs[top] = x;
id[top] = y;
nexts[top] = head[k];
head[k] = top++;
}
ll find(ll x, ll mod)
{
ll k = x % mod;
for (int i = head[k]; i != -1; i = nexts[i])
if (hs[i] == x)
return id[i];
return -1;
}
ll qmi(ll m, ll k, ll p)
{
ll res = 1 % p, t = m;
while (k)
{
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
ll BSGS(ll a, ll b, ll p, ll a1) //质数传1
{
memset(head, -1, sizeof(head));
top = 1;
a %= p, b %= p;
if (a1 == 1 && 1 % p == b % p)
return 0;
if (a == 0)
{
if (b == 0)
return 1;
else
return -1;
}
//unordered_map<ll, ll> hash; //map unordered_map 都试试
ll k = sqrt(p) + 1;
ll ak = 1;
for (ll i = 0; i < k; ++i)
{
ll t = ak * b % p;
insert(t, i, N);
//hash[t] = i;
ak = ak * a % p;
}
for (ll i = 0; i <= k; ++i)
{
/* if (hash.count(a1) && i * k - hash[a1] >= 0)
return i * k - hash[a1]; */
ll j = find(a1, N);
if (j != -1 && i * k - j >= 0)
return i * k - j;
a1 = a1 * ak % p;
}
return -1;
}
ll exBSGS(ll a, ll b, ll p)
{
a %= p, b %= p;
if (b == 1 || p == 1)
return 0;
ll cnt = 0, a1 = 1;
ll d = gcd(a, p);
while (d > 1)
{
if (b % d)
return -1;
p /= d;
b /= d;
a1 = (a1 * a / d) % p;
++cnt;
if (b == a1)
return cnt;
d = gcd(a, p);
}
ll res = BSGS(a, b, p, a1);
if (res == -1)
return -1;
else
return res + cnt;
}
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll p,a,b,x1,t;
scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t);
if(x1==t)
{
printf("1\n");
continue;
}
if(a==0)
{
if(t==b) printf("2\n");
else printf("-1\n");
continue;
}
if(a==1)
{
t=((t-x1)%p+p)%p;
if(t%gcd(b,p)!=0)
{
printf("-1\n");
continue;
}
ll temp=qmi(b,p-2,p);
ll ans=(t*temp)%p+1;
if(ans==p)
{
printf("%lld\n",ans);
continue;
}
ans=ans%p;
printf("%lld\n",ans);
continue;
}
ll temp=qmi(a-1,p-2,p);
ll up=(t+b*temp)%p;
ll down=(x1+b*temp)%p;
down=qmi(down,p-2,p);
ll bb=(up*down)%p;
//printf("%lld %lld %lld\n",a,bb,p);
ll ans=BSGS(a,bb,p,1);
if(ans!=-1) printf("%lld\n",ans+1);
else printf("-1\n");
}
}