╰( ̄▽ ̄)╭

小 W喜欢读 书,尤其喜欢读 书,尤其喜欢读《约翰克里斯 朵夫》。 最近小 W准备读一本新书,这本一共有 p页, 页码范围为 0..p -1。

小 W很忙,所以每天只能读一页书 。为了使事情有趣一些 ,他打算使用 NOI2012上学习的线性同余法生成 一个序列 ,来决定每天具体读哪一页 。

我们用 Xi来表示通过这种方法生成出来第 i个数 ,也即小 W第 i天会读 哪一页 。这个方法 需要设置 3个参数 a,b,X1,满足 0≤a,b,X1≤p-1,且 a, b,X1都是整数 。按照下面的公式 按照下面的公式生成出来一系列的 整数。

Xi+1=(aXi+b)modp

其中 mod p 表示前面的数除以 p的余数。

可以发现,这个序列中下一个数总是由上一个数生成的 ,而且每一项都在 0..p -1这个范围内 ,是一个合法的页码。 同时需要注意 ,这种方法有可能导致某两天读的页码完全一样 。

小 W非常急切 地想去读这本书的第t页。所以他想知道, 对于一组给定的 a, b,X1,如果使用线性同余法来生成每一天读的页码, 最早读到第t页是在哪一天,或者指出他永远不会读到第t页。

p<=109

(⊙ ▽ ⊙)

容易求出x的通项公式,

设c=ba−1,

xn=an−1(x1+c)−c


特殊情况的处理:

在此之前我们必须保证a!=1;

所以我们对于a=1的情况利用扩展欧几里得求解。

同时我们也得保证a!=0,因为当a=0并且n=1时,00是无意义的。

于是对于a=0的情况直接特判求解。


此时,题目要求的是:xn≡t(mod p),等价于:an−1(x1+c)−c≡t(mod p)。

移项可得:an−1≡t+cx1+c(mod p)


特殊情况的处理:

在此之前,我们还要保证x1和b不同时为0,否则会使得x1+c这个分母为0。

所以对于x1和b同时为0的情况特判求解。


令ans=n−1 , S=t+cx1+c,最终题目转化为求

aans≡S(mod p)

的最小正整数解。(关于ans)

于是就能套大步小步算法(BSGS algorithm)了。

( ̄~ ̄)

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#define ll long long
using namespace std;
const char* fin="jzoj3211.in";
const char* fout="jzoj3211.out";
const ll inf=0x7fffffff;
const ll maxh=1000007;
ll t,i,j,k,A,B,X1,n,mo;
ll h[maxh],minx[maxh];
bool noans;
ll hash(ll v){
ll k=v%maxh;
while (h[k] && h[k]!=v) k=(k+1)%maxh;
return k;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if (b==0){
x=1;
y=0;
return a;
}
ll r=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
return r;
}
ll qpower(ll a,ll b){
ll c=1;
while (b){
if (b&1) c=c*a%mo;
a=a*a%mo;
b>>=1;
}
return c;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%lld",&t);
while (t--){
scanf("%lld%lld%lld%lld%lld",&mo,&A,&B,&X1,&n);
if (A==0){
if (X1==n) printf("1\n");
else if (B==n) printf("2\n");
else printf("-1\n");
}else if (A==1){
ll x,y;
k=exgcd(mo,B,x,y);
if ((n-X1)%k) printf("-1\n");
else{
x*=(n-X1)/k;
y*=(n-X1)/k;
y=(y%(mo/k)+(mo/k))%(mo/k);
printf("%lld\n",y+1);
}
}else if (B==0 && X1==0){
if (X1==n) printf("1\n");
else printf("-1\n");
}else{
ll ks=(ll)sqrt(mo),tmp=qpower(A,ks),tmd=qpower(tmp,mo-2);
memset(h,0,sizeof(h));
memset(minx,0,sizeof(minx));
j=1;
for (i=0;i<ks;i++){
k=hash(j);
h[k]=j;
if (!minx[k] || minx[k]>i) minx[k]=i;
j=j*A%mo;
}
ll C=B*qpower(A-1,mo-2)%mo;
j=(n+C)*qpower(X1+C,mo-2)%mo;
noans=true;
for (i=0;i<=ks;i++){
k=hash(j);
if (h[k]){
ll ans=minx[k]+i*ks+1;
printf("%lld\n",ans);
noans=false;
break;
}
j=j*tmd%mo;
}
if (noans) printf("-1\n");
}
}
return 0;
}

(⊙v⊙)

对于一个有递推式的问题,可以考虑先求出通项公式,在对其因式分解。

【JZOJ3211】【SDOI2013】随机数生成器的更多相关文章

  1. 【BZOJ 3122】 [Sdoi2013]随机数生成器 (BSGS)

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1442  Solved: 552 Description ...

  2. bzoj3122 [SDOI2013]随机数生成器

    bzoj3122 [SDOI2013]随机数生成器 给定一个递推式, \(X_i=(aX_{i-1}+b)\mod P\) 求满足 \(X_k=t\) 的最小整数解,无解输出 \(-1\) \(0\l ...

  3. 洛咕 P3306 [SDOI2013]随机数生成器

    洛咕 P3306 [SDOI2013]随机数生成器 大力推式子??? \(X_{i}=\underbrace{a(a(\cdots(a(a}_{i-1个a}X_1+b)))\cdots)\) \(=b ...

  4. 【BZOJ3122】[Sdoi2013]随机数生成器 BSGS+exgcd+特判

    [BZOJ3122][Sdoi2013]随机数生成器 Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数.   接下来T行,每行有五个整数p,a,b, ...

  5. 【bzoj3122】: [Sdoi2013]随机数生成器 数论-BSGS

    [bzoj3122]: [Sdoi2013]随机数生成器 当a>=2 化简得 然后 BSGS 求解 其他的特判 : 当 x=t  n=1 当 a=1  当 a=0 判断b==t /* http: ...

  6. 【洛谷 P3306】[SDOI2013]随机数生成器 (BSGS)

    题目链接 怎么这么多随机数生成器 题意见原题. 很容易想到\(BSGS\)算法,但是递推式是\(X_{i+1}=(aX_i+b)\mod p\),这显然不是一个等比数列. 但是可以用矩阵乘法来求出第\ ...

  7. bzoj 3122: [Sdoi2013]随机数生成器

    #include<cstdio> #include<iostream> #include<map> #include<cmath> #define ll ...

  8. bzoj 3122 [Sdoi2013]随机数生成器(逆元,BSGS)

    Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数.    接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. ...

  9. BZOJ3122: [Sdoi2013]随机数生成器(BSGS)

    题意 题目链接 Sol 这题也比较休闲. 直接把\(X_{i+1} = (aX_i + b) \pmod P\)展开,推到最后会得到这么个玩意儿 \[ a^{i-1} (x_1 + \frac{b}{ ...

  10. bzoj千题计划259:bzoj3122: [Sdoi2013]随机数生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=3122 等比数列求和公式+BSGS #include<map> #include<c ...

随机推荐

  1. js中call、apply、bind的区别和应用

    一.总体概述 这三个方法都是改变函数本身的this指向的,但是略有不同 1.call 使用方法:函数名.call(this指向,展开的参数列表); 如果传入的this指向是null或者是undifin ...

  2. Ubuntn16.04修改pip源

    将python的pip源修改为中科大的镜像 cd ~ touch pip.conf sudo gedit pip.conf 在新打开的文件中写入: [global] trusted-host = py ...

  3. 计算机程序是怎么通过cpu,内存,硬盘运行起来的?

    虽然以前知道计算机里有CPU,内存,硬盘,显卡这么些东西,我还真不知道这些东西是怎么协作起来完成一段程序的,能写出程序却不懂程序,也不会向别人解释他们的关系,所以特意总结了一下,写的比较浅显,和我一样 ...

  4. IDEA常用插件整理

    1. 集成步骤 1.1. 配置环境变量 变量名:CMDER_ROOT 变量值:D:\Tool\cmder 1.2. IDEA中设置 settings->Tool->Terminal She ...

  5. Django项目: 5.新闻主页

    一.功能需求分析 1.功能 轮播图 推荐文章列表 文章标签导航 文章列表 分页 二.模型设计 根据功能分析,我们需要如下表 1.表和字段分析 文章分类表 文章表 文章评论表 推荐文章表 轮播图表 2. ...

  6. VC++1.5太伟大了

    功能样样俱全,一点不比现在的VS系列差 VC++1.5全貌,虽然很古老,但是已经可以了. 新建的文档试图,多文档工程,很像样 文档试图,单文档工程,已经非常像样了,和记事本差不多了 这是资源编辑器,寒 ...

  7. oracle基础学习(1)

    -解锁用户,需要使用dba权限conn sys/1234 as dba; alert user scott account unlock;/ --initcap方法,实现字符串首字符大写,其余字符小写 ...

  8. Leetcode429.N-ary Tree Level Order TraversalN叉树的层序遍历

    给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2,4], [5,6] ] 说明: 树的深度不会超过 100 ...

  9. 百度地图JavaScript API申请密钥注意要点

    1.应用类型:浏览器端 2.启用服务:Javascript API要勾选 3.IP白名单:*即可

  10. TZ_06_SpringMVC的入门程序

    SpringMVC的入门程序 1. 创建WEB工程,引入开发的jar包 1. 具体的坐标如下 2. 配置核心的控制器(配置DispatcherServlet) 1. 在web.xml配置文件中核心控制 ...