BZOJ-3122 [Sdoi2013]随机数生成器(BSGS)
题目描述
有四个参数 \(p,a,b,x_1\),满足 \(0\leq a,b,x_1<p\),按照下面的式子生成一系列整数:
\[x_{i+1}\equiv a\times x_i+b\pmod {p}
\]
给出一个数字 \(t\),求出 \(x_i=t\) 的最小下标 \(i\)。
数据范围:\(1\leq T\leq 50,0\leq a,b,x_1,t<p,2\leq p\leq 10^9\),\(p\) 为质数。
分析
\[x_{i+1}\equiv ax_i+b\pmod {p}\\
x_{i+1}+\frac{b}{a}\equiv ax_{i}+b+\frac{b}{a}\pmod {p}\\
ax_{i+1}+b\equiv a^2x_{i}+ab+b\pmod {p}\\
x_{i+2}\equiv a^2x_{i}+ab+b\pmod {p}
\]
则:
\[x_2\equiv ax_1+b\pmod {p}\\
x_{3}\equiv a^2x_{1}+ab+b\pmod {p}\\
x^4\equiv a^3x_1+a^2b+ab+b\pmod p\\
\cdots\\
x_{i}\equiv a^{i-1}x_1+b(a^{i-2}+a^{i-1}+\cdots+a+1)\equiv a^{i-1}x_1+b\sum_{k=0}^{i-2}a^{k}\pmod {p}
\]
即判断关于 \(i\) 的方程 \(t\equiv a^{i-1}x_1+b\displaystyle\sum_{k=0}^{i-2}a^{k}\pmod {p}\) 是否有整数解。
\[t\equiv a^{i-1}x_1+b\frac{1-a^{i-1}}{1-a}\pmod {p}\\
t\equiv a^{i-1}x_1+\frac{b}{1-a}-\frac{b}{1-a}·a^{i-1}\pmod {p}\\
t\equiv a^{i-1}(x_1-\frac{b}{1-a})+\frac{b}{1-a}\pmod {p}\\
a^{i-1}\equiv \frac{t-\frac{b}{1-a}}{x_1-\frac{b}{1-a}}\pmod {p}
\]
用 \(\text{BSGS}\) 算法求解即可。
注意:当 \(t=x_1\) 时,答案为 \(1\);当 \(a=0\) 时,\(x_i=b\);当 \(a=1\) 时,\(x_i\equiv x_1+b(i-1)\pmod {p}\),移项,\(i\equiv (t-x_1)·b^{-1}+1\pmod {p}\),求 \(i\) 即可。\(t=p\) 时要输出 \(p\) 而不是 \(0\)。
代码
#include<bits/stdc++.h>
using namespace std;
long long p,a,b,x1,t;
long long quick_pow(long long a,long long b,long long p)
{
long long ans=1;
while(b)
{
if(b&1)
ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
map<long long,long long> mp;
long long BSGS(long long a,long long b,long long p)
{
a=a%p,b=b%p;
long long m=sqrt(p)+1;
long long ans=b;
for(long long i=0;i<m;i++)
{
mp[ans]=i;
ans=ans*a%p;
}
long long temp=quick_pow(a,m,p);
ans=1;
for(long long i=1;i<=m;i++)
{
ans=1ll*ans*temp%p;
if(mp.count(ans))
return i*m-mp[ans];
}
return -1;
}
int main()
{
int T;
cin>>T;
while(T--)
{
mp.clear();
scanf("%lld %lld %lld %lld %lld",&p,&a,&b,&x1,&t);
if(t==x1)
{
puts("1");
continue;
}
if(a==0)
{
if(b==t)
puts("2");
else
puts("-1");
continue;
}
if(a==1)
{
t=((t-x1)%p+p)%p;
if(t%__gcd(b,p)!=0)
puts("-1");
else
{
if((t*quick_pow(b,p-2,p)+1)%p==0)
cout<<p<<endl;
else
cout<<(t*quick_pow(b,p-2,p)+1)%p<<endl;
}
continue;
}
long long fz=((t-b*quick_pow(1-a,p-2,p)%p)+p)%p;
long long fm=quick_pow(((x1-b*quick_pow(1-a,p-2,p))%p+p)%p,p-2,p);
long long ans=BSGS(a,fz*fm%p,p);
if(ans==-1)
puts("-1");
else
cout<<ans+1<<endl;
}
return 0;
}
posted on 2020-11-16 11:17 DestinHistoire 阅读(61) 评论(0) 收藏 举报