bzoj 3122 随机数生成器 - BSGS
Description
Input
输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。
接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。
注意:P一定为质数
Output
共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。
Sample Input
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1
Sample Output
3
-1
HINT
0<=a<=P-1,0<=b<=P-1,2<=P<=10^9
题目大意
给定一个序列$X$的首项$x_{1}$,序列$X$满足递推关系$x_{n + 1} = (a\cdot x_{n} + b)\mod p$,其中这里的$mod$表示求余数。问序列中哪个数第一次为$t$,或者输出无解。
显然递推关系对方程不是特别友好,所以考虑求序列的通项。
由于这里用特征根的方法来求会很繁琐,所以直接展开:
$x_{n} = \left ( a\cdot x_{n - 1} + b \right ) \mod p$
$x_{n} = \left ( a^{2}\cdot x_{n - 2} + ab + b \right ) \mod p$
$x_{n} = \left ( a^{n - 1}\cdot x_{1} + a^{n-2}b + \cdots + ab + b \right ) \mod p$
用等比数列求和公式得到:
$x_{n} = \left [ a^{n - 1}\cdot x_{1} + \frac{\left (a^{n - 1} - 1 \right )b}{a - 1}\right ] \mod p\ \ \ (a \neq 1)$
$x_{n} = \frac{a^{n - 1}\cdot x_{1}\left ( a - 1 \right ) + \left (a^{n - 1} - 1 \right )b}{a - 1} \mod p\ \ \ (a \neq 1)$
$x_{n} = \frac{a^{n - 1}\cdot\left [ x_{1}\left ( a - 1 \right ) + b \right ] - b}{a - 1} \mod p\ \ \ (a \neq 1)$
然后再移项:
$a^{n - 1}\cdot\left [ x_{1}\left ( a - 1 \right ) + b \right ] \equiv \left ( a - 1 \right )x_{n} + b \pmod{p}\ \ \ (a \neq 1)$
BSGS解方程即可。
继续考虑$a = 1$的情况,此时有:
$x_{n} \equiv x_{1} + \left ( n - 1 \right )b \pmod{p} \ \ \left ( a = 1 \right )$
写成不定方程的形式:
$n\cdot b + k\cdot p = x_{n}+ b - x_{1}\ \ \left ( a = 1 \right )$
直接扩欧算答案。
注意一个细节,扩欧如果算出答案模$p$为0,那么应该输出$p$,因为这里求的是最小正余数。
似乎$a = 0$的时候,要加点处理,不然扔进去的东西变成负数,BSGS也会出事情。干脆直接特判。
Code
/**
* bzoj
* Problem#3122
* Accepted
* Time: 268ms
* Memory: 2028k
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef bool boolean; typedef class HashMap {
private:
static const int M = ;
public:
int ce;
int h[M], key[M], val[M], next[M]; HashMap() { } void insert(int k, int v) {
int ha = k % M;
for (int i = h[ha]; ~i; i = next[i])
if (key[i] == k) {
val[i] = v;
return;
}
++ce, key[ce] = k, val[ce] = v, next[ce] = h[ha], h[ha] = ce;
} int operator [] (int k) {
int ha = k % M;
for (int i = h[ha]; ~i; i = next[i])
if (key[i] == k)
return val[i];
return -;
} void clear() {
ce = -;
memset(h, -, sizeof(h));
}
}HashMap; int qpow(int a, int pos, int m) {
int pa = a, rt = ;
for ( ; pos; pos >>= , pa = pa * 1ll * pa % m)
if (pos & )
rt = rt * 1ll * pa % m;
return rt;
} int gcd (int a, int b) {
return (b) ? (gcd(b, a % b)) : (a);
} void exgcd(int a, int b, int& d, int &x, int &y) {
if (!b)
d = a, x = , y = ;
else {
exgcd(b, a % b, d, y, x);
y -= (a / b) * x;
}
} int inv(int a, int n) {
int d, x, y;
exgcd(a, n, d, x, y);
return (x < ) ? (x + n) : (x);
} int T;
int p, a, b, x1, t; inline void init() {
scanf("%d%d%d%d%d", &p, &a, &b, &x1, &t);
} HashMap mp;
inline int ind(int x, int a, int p, int pro) {
mp.clear();
int cs = sqrt(p - + 0.5);
int ainv = inv(x, p), iap = a * 1ll * qpow(ainv, cs - , p) % p;
for (int i = cs - ; ~i; i--, iap = iap * 1ll * x % p)
mp.insert(iap, i);
int cp = qpow(x, cs, p), pw = pro;
for (int i = ; i < p; i += cs, pw = pw * 1ll * cp % p)
if (~mp[pw])
return mp[pw] + i;
return -;
} inline int solve1() {
if (!b) return (t == x1) ? () : (-);
int d, x, y, go = t + b - x1;
exgcd(b, p, d, x, y);
x = x * 1ll * go % p;
return (x <= ) ? (x + p) : (x);
} inline void solve() {
if (a == )
printf("%d\n", (t == x1) ? () : ((b == t) ? () : (-)));
else if (a == )
printf("%d\n", solve1());
else
printf("%d\n", ind(a, ((a - ) * 1ll * t + b) % p, p, (x1 * 1ll * (a - ) + b) % p) + );
} int main() {
scanf("%d", &T);
while (T--) {
init();
solve();
}
return ;
}
bzoj 3122 随机数生成器 - BSGS的更多相关文章
- BZOJ 3122 随机数生成器
http://www.lydsy.com/JudgeOnline/problem.php?id=3122 题意:给出p,a,b,x1,t 已知xn=a*xn-1+b%p,求最小的n令xn=t 首先,若 ...
- 【BZOJ 3122】 [Sdoi2013]随机数生成器 (BSGS)
3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1442 Solved: 552 Description ...
- 【BZOJ-3122】随机数生成器 BSGS
3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1362 Solved: 531[Submit][Sta ...
- 【BZOJ3122】[Sdoi2013]随机数生成器 BSGS+exgcd+特判
[BZOJ3122][Sdoi2013]随机数生成器 Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b, ...
- bzoj 3122 : [Sdoi2013]随机数生成器 BSGS
BSGS算法 转自:http://blog.csdn.net/clove_unique 问题 给定a,b,p,求最小的非负整数x,满足$a^x≡b(mod \ p)$ 题解 这就是经典的BSGS算法, ...
- Bzoj 3122 [Sdoi2013]随机数生成器(BSGS+exgcd)
Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. 注意:P一定为质数 Outp ...
- BZOJ3122 随机数生成器——BSGS
题意 链接 给定 $p,\ a,\ b, \ x_1$,现有一数列 $$x_{i+1} \equiv (ax_i + b) \ mod \ p$$ 求最小的 $i$ 满足 $x_i = t$ 分析 代 ...
- [BZOJ]3671 随机数生成器(Noi2014)
洛谷上卡不过去的朋友们可以来看看小C的程序(小C才不是标题党呢!) Description Input 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子 ...
- BZOJ3122: [Sdoi2013]随机数生成器(BSGS)
题意 题目链接 Sol 这题也比较休闲. 直接把\(X_{i+1} = (aX_i + b) \pmod P\)展开,推到最后会得到这么个玩意儿 \[ a^{i-1} (x_1 + \frac{b}{ ...
随机推荐
- 从0开始搭建vue+webpack脚手架(二)
接着从0开始搭建vue+webpack脚手架(一) 三.配置webpack-dev-server 1. webpack-dev-server自带一个node的服务器, 项目在服务端运行的同时可以实现热 ...
- 寻路——AI
小球找到目标位置, 必要时候进行跳跃 进行跳跃时,需要在cube上加上 Off Mesh Link 组件,并添加起跳位置和目标位置 在static位置选Navigation static 编写脚本 ...
- JAVA_Stream_练习
package airycode_java8.nice7; import airycode_java8.nice1.Employee; import org.junit.Test; import ja ...
- c# 使用MS SqlServer,连接成功,但是还报异常A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0。。。。
c# 使用MS SqlServer,连接成功,但是还报异常A connection was successfully established with the server, but then an ...
- SQL Server如何将Id相同的字段合并,并且以逗号隔开
需要用到stuff函数: 例: id name 1 张三 1 李四 ...
- install Maven
工欲善其事,必先利其器.咱们也来玩玩 Maven 这货吧!先得去下载一个. 准备工作 java开发环境(JDK) maven下载地址:http://maven.apache.org/release-n ...
- linux命令目录
一.文件和目录.(文件目录的增删改查) ls pwd cd mkdir touch rmdir ln dd rm cp mv nl cat tac more less head tail stat # ...
- JavaScript循环和数组常用操作
while循环 语法: do while循环 语法:do{循环体}while(条件表达式); 特点:do while循环不管条件是否成立,无论如何循环体都会执行一次. 使用场合:用户输入密码,如果密码 ...
- 准备mybatis-spring
spring-mybatis下载:https://mvnrepository.com/artifact/org.mybatis/mybatis-spring 导入mybatis-spring-2.0. ...
- QT 通过QNetworkReply *获取对应请求的URL地址
[1]QT 通过QNetworkReply *获取对应请求的URL地址 reply->url().toString(); Good Good Study, Day Day Up. 顺序 选择 循 ...