您的位置:首页 > 其它

bzoj3122【SDOI2013】随机数生成器

2016-04-13 00:15 357 查看

3122: [Sdoi2013]随机数生成器

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1204  Solved: 471

[Submit][Status][Discuss]

Description



Input

输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。  

 

接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。 

注意:P一定为质数

Output

共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。 

Sample Input

3

7 1 1 3 3

7 2 2 2 0

7 2 2 2 1

Sample Output

1

3

-1

HINT

0<=a<=P-1,0<=b<=P-1,2<=P<=10^9

扩展欧几里得求逆元+BSGS

题解戳这里:http://hzwer.com/6963.html

(公式恐惧症飘过,不带走一片云彩)

注意各种特殊情况的判断,WA了很多次...

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
using namespace std;
ll T,p,a,b,x1,t;
map<ll,int> mp;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline ll getpow(ll x,ll y,ll p)
{
ll ret=1;
for(;y;y>>=1,x=x*x%p) if (y&1) ret=ret*x%p;
return ret;
}
inline ll exgcd(ll a,ll b,ll &x,ll &y)
{
if (!b){x=1;y=0;return a;}
ll ret=exgcd(b,a%b,x,y);
ll t=x;x=y;y=t-a/b*y;
return ret;
}
inline ll bsgs(ll a,ll b,ll p)
{
if (b==1) return p-1;
ll m=ceil(sqrt(p));
mp.clear();
ll tmp=1,inv=getpow(a,p-2,p);
F(i,0,m)
{
ll h=b*tmp%p;
if (!mp[h]) mp[h]=i;
tmp=tmp*inv%p;
}
tmp=1;
ll base=getpow(a,m,p);
F(i,0,m)
{
if (mp[tmp])
{
ll ret=i*m+mp[tmp];
return ret;
}
tmp=tmp*base%p;
}
return -1;
}
inline ll calc1()
{
ll c=((t-x1)%p+p)%p,x,y;
ll tmp=exgcd(b,p,x,y);
if (c%tmp) return -1;
return (x*c/tmp%p+p)%p+1;
}
inline ll calc2()
{
ll c=getpow(a-1,p-2,p);
ll t1=(b*c%p+x1)%p,t2=(b*c%p+t)%p,x,y;
if (t1==0)
{
if (t2==0) return 1;
else return -1;
}
if (t2==0) return -1;
ll tmp=exgcd(t1,p,x,y);
if (t2%tmp) return 0;
t2/=tmp;x=(x%p+p)%p;
ll t=bsgs(a,x*t2%p,p);
if (t==-1) return -1;
else return t+1;
}
inline ll getans()
{
if (x1==t) return 1;
if (a==0) return b==t?2:-1;
if (a==1) return calc1();
return calc2();
}
int main()
{
int T=read();
while (T--)
{
p=read();a=read();b=read();x1=read();t=read();
printf("%lld\n",getans());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: