bzoj3122 [Sdoi2013]随机数生成器(bsgs+扩欧+数列)
来源:互联网 发布:百度怎么推广淘宝店铺 编辑:程序博客网 时间:2024/05/17 04:53
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
分析:
刚刚学了数列,看到这道题就不那么难受了
X[i+1]=(aX[i]+b)mod p
X[i+1]+u=a(X[i]+u)
(a-1)u=b
u=b/(a-1)
X[i+1]+u=(X[1]+u)*a^i
a^i=(X[i+1]+u)/(X[1]+u) (mod p)
已知X[i+1]
实际上就是
x^i=z (mod p),求解最小i
最后答案就是i+1
然而这只适用于a!=1的情况
当a==1的时候
这就是一个等差数列了
X[i+1]=X[1]+b*i
X[i+1]-X[1]=b*i
设x=i,z=X[i+1]-X[1]
式子就可以化简成
b*i=z (mod p)
b*i+k*p=z
我们先用扩欧求解b*i+k*p=1
最后把答案*z+1就可以了
注意
如果z不是gcd(b,p)的倍数,那么无解
一开始我的算法是:
i=(X[i+1]-X[1])*inv(b)
但是这样秒WA,我觉得一概是无法判断无解导致的
注意:p一定为质数
这样求逆元就可以用费马小定理了
tip
注意特殊情况的特判
x1==t,ans=1
a==0&&b==t,ans=2
a==0&&b!=t,ans=-1
一直连WA,最后才发现是主程序的问题
一个输出后忘了回车!!!
这里写代码片#include<cstdio>#include<iostream>#include<cstring>#include<map>#include<cmath>#define ll long longusing namespace std;map<ll,int> mp;ll p,z,t,x1,a,b,x,y;ll gcd(ll a,ll b){ ll r=a%b; while (r) { a=b;b=r; r=a%b; } return b;}ll KSM(ll a,ll b,ll p){ a%=p; ll t=1; while (b) { if (b&1) t=(t%p*a%p)%p; b>>=1; a=(a%p*a%p)%p; } return t%p;}int bsgs(ll x,ll z,ll p){ mp.clear(); x%=p; z%=p; if (x==0&&z==0) return 2; if (x==0) return -1; ll m=(ll)ceil(sqrt((double)p)),now=1; mp[1]=m+1; for (int i=1;i<m;i++) { now=(now%p*x%p)%p; if (!mp[now]) mp[now]=i; } ll inv=1,tmp=KSM(x,p-m-1,p); for (int k=0;k<m;k++) { int i=mp[(z%p*inv%p)%p]; if (i) { if (i==m+1) i=0; return k*m+i+1; } inv=(inv%p*tmp%p)%p; } return -1;}void exgcd(ll a,ll b){ if (b==0) { x=1; y=0; return; } else { exgcd(b,a%b); int tt=y; y=x-(a/b)*y; x=tt; }}ll inv(ll a,ll p){ return KSM(a,p-2,p);}int main(){ int T; scanf("%d",&T); while (T--) { scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x1,&t); if (x1==t) { printf("1\n");continue; } else if (a==0) { if (b==t) printf("2\n"); else printf("-1\n"); continue; } else if (a==1) //等差数列 { z=((t-x1)%p+p)%p; if (z%gcd(b,p)!=0) { printf("-1\n"); continue; } exgcd(b,p); x=(x%p*z%p)%p; printf("%lld\n",(x%p+p)%p+1); } else //等比 { ll u=(b%p*inv(a-1,p)%p)%p; //u=b/(a-1) t=(t%p+u%p)%p; x1=(x1%p+u%p)%p; z=(t%p*inv(x1,p)%p)%p; //(X[i+1]+u)/(X[1]+u) printf("%d\n",bsgs(a,z,p)); } } return 0;}
- bzoj3122 [Sdoi2013]随机数生成器(bsgs+扩欧+数列)
- 【bzoj3122】[Sdoi2013]随机数生成器 BSGS
- 【BZOJ3122】【SDOI2013】随机数生成器(快速幂+BSGS)
- bzoj3122 随机数生成器 BSGS
- BZOJ3122: [Sdoi2013]随机数生成器
- bzoj3122 [Sdoi2013]随机数生成器
- bzoj3122【SDOI2013】随机数生成器
- bzoj3122: [Sdoi2013]随机数生成器
- 【bzoj3122】【SDOI2013】 随机数生成器
- BZOJ3122 && XOJ17 [Sdoi2013]随机数生成器
- BZOJ3122 [Sdoi2013]随机数生成器 数论
- bzoj3122 随机数生成器 BSGS+费马小定理求逆元
- BZOJ-3122-随机数生成器-SDOI2013-BSGS
- BZOJ 3122 [Sdoi2013]随机数生成器 BSGS
- BZOJ 3122: [Sdoi2013]随机数生成器 ex_gcd+BSGS
- Bzoj 3122 [Sdoi2013]随机数生成器(BSGS+exgcd)
- bzoj 3122 随机数生成器 (BSGS)
- 【JZOJ3211】【SDOI2013】随机数生成器
- 字符串和json的相互转换---JSON.parse()和JSON.stringify()
- ArrayList和Vector的区别,HashMap和Hashtable的区别。
- 穿插纸条 (第73-90关)终点和连通性对于拐点的限制
- mongodb 误删除集合恢复 误删除表数据恢复
- 自制控件,类型“Appliaction.dd”中不存在类型名称“dd”
- bzoj3122 [Sdoi2013]随机数生成器(bsgs+扩欧+数列)
- 多线程PING IP+端口号!(源码),附非多线程时间测试对比。。
- 虚幻引擎4系列教程2(霜之小刀)(附视频)--第一人称场景建模
- hbase客户端api--建表
- 随笔:浏览器解析动态请求返回页面过程分析
- hdu-2063-过山车-二分匹配-匈牙利-java
- Kali Linux入门第一课 | 内网抓取用户浏览图片
- leetcode171. Excel Sheet Column Number
- app分析 名词解释 app购买量