bzoj 3122 随机数生成器 - BSGS
Description
.jpg)
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}{ ...
随机推荐
- shell基础:位置参数变量
位置参数名称,作用不变.变得是传入参数. 抽象问题,大多为年长资格老师少数年轻老师,故而问的技术细节少,抽象理论知识多,比如什么是软件工程,问什么会有软件工程.有事注重的是品质,有的注重出身. 每种都 ...
- 21Oracle数据库和实例
Oracle数据库:相关的操作系统文件(即储存在计算机硬盘上的文件)的集合,这些文件组织在一起,成为一个逻辑整体,即为Oracle数据库.物理存在 Oracle实例:位于物理内存里的数据结构,它由操作 ...
- JAVA8流操作
* Stream 的三个操作步骤: * 1创建Stream * 2中间操作 * 3终止操作 package airycode_java8.nice6; import airycode_java8.ni ...
- jQuery-图片放大镜
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jQuery绑定事件方法及区别(bind,click,on,live,one)
第一种方式: ? 1 2 3 4 5 $(document).ready(function(){ $("#clickme").click(function(){ alert(& ...
- sql server行列转化和行列置换
行列转换: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 想变成(得到如下结果): 姓名 语文 数学 物理 ---- - ...
- vss使用笔记
一.四大代码/文档管理软件 (1) git:具有PR(push request)特性,推送请求.需要负责人审核后才能推送.另外,在推送过程中,git会预编译(合并),分布式代码管理(客户端本地 ...
- html5-表单和input元素用法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- 缓存 Memached
https://github.com/enyim/EnyimMemcached http://www.newasp.net/soft/63735.html#downloaded/ http://blo ...
- Lua逻辑操作符
[1]逻辑操作符and.or和not 应用示例: ) ) -- nil ) -- false ) ) ) ) ) ) ) print(not nil) -- ture print(not false) ...