bzoj3122【SDOI2013】随机数生成器
2016-04-13 00:15
357 查看
3122: [Sdoi2013]随机数生成器
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 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
37 1 1 3 3
7 2 2 2 0
7 2 2 2 1
Sample Output
13
-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());
}
}
相关文章推荐
- 【模拟】【codeforces】451A Game With Sticks
- gradle学习笔记(三) Groovy闭包
- Hdu 4734-F(x) 数位dp
- 单例模式详解
- 多台Exchange服务器设置内网MX记录
- 项目记录36--tolua 框架真机成功热跟新搞定 + 简单池子PrefabsPool.lua
- 个人认为最好的Mac端的视频播放软件___movist
- Sharepoint构建轻量型应用之InfoPath的简单应用案例!
- bzoj3007 拯救小云公主
- 若干数据结构 && 算法面试题【一】(更新完毕)
- leetcode 110. Balanced Binary Tree
- Linux环境下在Tomcat上部署JavaWeb工程
- ethtool命令介绍
- Android BottomNavigationBar的使用
- bzoj3004 吊灯
- DrawIndexedPrimitive参数详解
- JQuery攻略读书笔记---第2章 数组
- 王海实名举报:工商总局等长期纵容百度虚假广告
- Java加密解密工具(适用于JavaSE/JavaEE/Android)
- PHP网页抓取之抓取百度贴吧邮箱数据代码分享