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}{ ...
随机推荐
- android 注入so
https://www.52pojie.cn/thread-564459-1-1.html
- PyQT5速成教程-3 布局管理
本文由 沈庆阳 所有,转载请与作者取得联系! 布局(Layout)管理 Qt Designer中,在工具箱中最上方可以看到有4种布局.分别是垂直布局.水平布局.栅格布局和表单布局. 四种布局 布局 ...
- Winform下如何上传图片并显示出来。同时保存到数据库
通常,我们在开发软件或者网站是否,通常有时候需要添加图片,我们怎么做呢,直接贴例子. 前提是添加openFileDialog控件哈 #region 定义公共的类对象及变量 SqlConn ...
- 在caffe-ssd的环境搭建中遇到报错信息:Makefile:588: recipe for target '.build_release/cuda/src/caffe/layers/softmax_loss_layer.o' failed
错误原因: 1.计算机没有安装GPU 2.有GPU但是NVCCFLAGS设置错误 解决方法: 1.对没有GPU的计算机,需要将Makefile中的CPU之前的#注释去掉,是的caffe运行的处理器进行 ...
- [ Windows BAT Script ] BAT 脚本获取windows权限
BAT 脚本获取windows权限 @echo off echo I am trying to run as Administrator %1 %2 ver|find "5."&g ...
- EXTENDED LIGHTS OUT (高斯消元)
In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual ...
- css中选项卡的实现
制作一个简单的选项卡,以供初学者参考:关于css书写的比较粗糙.请见谅 <!DOCTYPE html><html lang="en"><head> ...
- Python 字典(Dictionary) values()方法
描述 Python 字典(Dictionary) values() 函数以列表返回字典中的所有值. 语法 values()方法语法: dict.values() 参数 NA. 返回值 返回字典中的所有 ...
- WIN7系统怎样增加C盘空间
具体操作参考:https://jingyan.baidu.com/article/215817f78e05c01eda142385.html
- vue-cli项目npm run build后,index.html无法在浏览器打开