题目描述

给出递推公式 $x_{i+1}=(ax_i+b)\mod p$ 中的 $p$、$a$、$b$、$x_1$ ,其中 $p$ 是质数。输入 $t$ ,求最小的 $n$ ,使得 $x_n=t$ 。若不存在则输出-1。

输入

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

注意: p 一定为质数

输出

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

样例输入

3
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1

样例输出

1
3
-1


题解

BSGS思想的利用

(以下为思考过程)

早就知道网上的大部分题解:把通项公式变形为$x_{i+1}+c=a(x_i+c)\mod p$,然后转化为BSGS的经典方程$a^x\mod p=c$来求解。

然而这样需要exgcd之类的,还需要乱七八糟的特判,代码少说也有80+行。

考虑:直接利用BSGS的meet-in-the-middle思想,而不是无脑套方程求解。

(以上为思考过程)

为了方便,设$f(x)=(ax+b)\mod p$,$f^d(x)$表示$f(x)$的$d$次复合,即$f(f(...(x)))$,其中$f$的个数为$d$。

我们要求的就是满足$f^n(x_1)=t$的最小的$n$。

首先根据抽屉(鸽笼)原理,如果有解则一定不超过$p$。

把答案$n$写成$km-l$的形式,其中$m=\lceil\sqrt n\rceil$。

那么我们要求的就是$f^{km-l}(x_1)=t$。

我们把这个式子左右同时复合$l$层,变为$f^{km}(x_1)=f^l(t)$。

由于一次函数复合以后还是一次函数,因此可以直接处理出$f^l(x)$和$f^{km}(x)$中一次项和常数项的系数。具体方法:$a(cx+d)+b=acx+ad+b$。

然后把所有的$f^{km}(x_1)$按照处理出的系数算出来,放到哈希表中(代码中使用了map),其中值相同的只取$k$较小的。

再枚举$l$,按照处理出的系数算出$f^l(t)$,看哈希表中是否有这个数即可,如果有则用$km-l$更新答案。

思考一下为什么一般情况下这样是对的:因为$p$是足够大的质数,因此所有数在模意义下都是存在的,并且存在唯一的逆。所以对于已知的$(cx+d)\mod p=e$,知道$e$可以直接推出$x$。

这个做法当$a=0$时不成立,因为不存在唯一的逆。因此需要特殊处理。

时间复杂度$O(\sqrt n\log n)$

代码只有40行左右^_^

#include <map>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
map<ll , ll> mp;
map<ll , ll>::iterator it;
ll u[50010] , v[50010];
int main()
{
int T;
scanf("%d" , &T);
while(T -- )
{
ll p , a , b , x , t , m , i , ans = 1ll << 62;
scanf("%lld%lld%lld%lld%lld" , &p , &a , &b , &x , &t);
if(!a)
{
if(t == x) puts("1");
else if(t == b) puts("2");
else puts("-1");
}
else
{
mp.clear() , m = ceil(sqrt(p));
u[0] = 1 , v[0] = 0;
for(i = 1 ; i <= m ; i ++ ) u[i] = u[i - 1] * a % p , v[i] = (a * v[i - 1] + b) % p;
for(i = 1 ; i <= m ; i ++ )
{
x = (x * u[m] + v[m]) % p;
if((it = mp.find(x)) == mp.end())
mp[x] = i;
}
for(i = 1 ; i <= m ; i ++ )
if((it = mp.find((t * u[i] + v[i]) % p)) != mp.end())
ans = min(ans , it->second * m - i + 1);
if(ans == 1ll << 62) puts("-1");
else printf("%lld\n" , ans);
}
}
return 0;
}

【bzoj3122】[Sdoi2013]随机数生成器 BSGS思想的利用的更多相关文章

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

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

  2. [bzoj3122][SDOI2013]随机数生成器 ——BSGS,数列

    题目大意 给定递推序列: F[i] = a*F[i-1] + b (mod c) 求一个最小的i使得F[i] == t 题解 我们首先要化简这个数列,作为一个学渣,我查阅了一些资料: http://d ...

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

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

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

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

  5. 【BZOJ-3122】随机数生成器 BSGS

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1362  Solved: 531[Submit][Sta ...

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

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

  7. BZOJ3122 [Sdoi2013]随机数生成器 【BSGS】

    题目 输入格式 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. 注意:P一定为质数 输出 ...

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

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

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

    BSGS算法 转自:http://blog.csdn.net/clove_unique 问题 给定a,b,p,求最小的非负整数x,满足$a^x≡b(mod \ p)$ 题解 这就是经典的BSGS算法, ...

随机推荐

  1. classList属性详解

    之前我们要操作一个DOM元素的class属性,需要对这个DOM的class进行繁琐的循环判断,而现在HTML5为每个元素定义了classLlist属性,用于在元素中添加,移除及切换 CSS 类.该属性 ...

  2. Java : 多态表现:静态绑定与动态绑定(向上转型的运行机制)

    本来想自己写写的,但是看到有人分析的可以说是很清晰了,故转过来. 原文地址:http://www.cnblogs.com/ygj0930/p/6554103.html 一:绑定 把一个方法与其所在的类 ...

  3. C语言实例解析精粹学习笔记——30

    实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...

  4. dotnet core 数据库

    dotnet core 数据库 程序开发过程中,需要使用数据对数据进行存储,分析等.通常而言都会使用ORM来实现关系数据库与实体对象的转化,过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持 ...

  5. 关于C++类模板无法解析的问题

    自己写了一个C++模板类,可是在vs2012中死活显示无法解析它的成员函数. 开始怎么也想不通,因为我是按照普通方式布置的:头文件放声明,在同名源文件中放实现,并包含其头文件. 后来百度了一下才发现, ...

  6. php杂记——1(基础知识与文件读写)

    1.变量前面需要加美元符号"$",常量则不需要: define('PRICE',100); echo PRICE; 2.用一个变量的值作为另一个变量的名称可以得到类似C中的指针变量 ...

  7. This content database has a schema version which is not supported in this farm.

          I want to move the website to another server. The new server has reinstall Sharepoint2013 serv ...

  8. Anytime项目开发记录4

    做事情列表,我在程序中命名为“正在做”. 这是一个Fragment,应用的主页面,由一个MainActivity加上DoingListFragment和PersonFragment组成.PersonF ...

  9. js学习日记-常用正则符号参考

    预定义类 量词 贪婪.惰性.支配性量词 前瞻 边界 RegExp是全局对象,RegExp.$1...$9是全局属性.当执行任意正则表达式匹配操作时,JavaScript会自动更新全局对象RegExp上 ...

  10. ibdata1文件损坏时恢复InnoDB单表测试

      Preface       ibdata1 file is a shared system tablespace of innodb engine.Although we always set v ...