题意:给你一个数列,a1 = x,ai = (A * ai-1 + B) % P,求第一个是t的是哪一项,或者永远不会有t。

解:循环节不会超过P。我们使用BSGS的思想,预处理从t开始跳√P步的,插入Hash表内。

然后每次把a1跳√P步,来看是否在Hash表中存在。

这样发现我们有40,WA了60分。为什么呢?考虑是否存在两个数x和y,它们跳一次之后一样了。发现这种情况只会出现在A = 0的时候,于是特判掉A = 0。可获得100分。

  1. #include <bits/stdc++.h>
  2.  
  3. const int N = ;
  4.  
  5. int MO, A, B, op, aim;
  6.  
  7. inline int qpow(int a, int b) {
  8. int ans = ;
  9. while(b) {
  10. if(b & ) {
  11. ans = 1ll * ans * a % MO;
  12. }
  13. a = 1ll * a * a % MO;
  14. b = b >> ;
  15. }
  16. return ans;
  17. }
  18.  
  19. namespace Hash {
  20. struct Node {
  21. int nex, v, id;
  22. }node[N]; int tp;
  23. const int mod = ;
  24. int e[mod];
  25. inline void clear() {
  26. tp = ;
  27. memset(e, , sizeof(e));
  28. return;
  29. }
  30. inline void insert(int v, int id) {
  31. int x = v % mod;
  32. for(int i = e[x]; i; i = node[i].nex) {
  33. if(node[i].v == v) {
  34. node[i].id = id;
  35. return;
  36. }
  37. }
  38. node[++tp].nex = e[x];
  39. node[tp].v = v;
  40. node[tp].id = id;
  41. e[x] = tp;
  42. return;
  43. }
  44. inline int find(int v) {
  45. int x = v % mod;
  46. for(int i = e[x]; i; i = node[i].nex) {
  47. if(node[i].v == v) {
  48. return node[i].id;
  49. }
  50. }
  51. return -;
  52. }
  53. }
  54.  
  55. inline void solve() {
  56. Hash::clear();
  57. scanf("%d%d%d%d%d", &MO, &A, &B, &op, &aim);
  58. if(op == aim) {
  59. printf("%d\n", );
  60. return;
  61. }
  62. if(A == ) {
  63. if(B == aim) {
  64. printf("2\n");
  65. }
  66. else {
  67. printf("-1\n");
  68. }
  69. return;
  70. }
  71. int T = sqrt((double)MO);
  72. for(int i = ; i < T; i++) {
  73. Hash::insert(aim, i);
  74. //printf("Hash insert %d %d \n", aim, i);
  75. aim = (1ll * A * aim % MO + B) % MO;
  76. }
  77. int c = qpow(A, T), d;
  78. if(A == ) {
  79. d = 1ll * B * T % MO;
  80. }
  81. else {
  82. d = (1ll * (c - ) * qpow(A - , MO - ) % MO * B % MO + MO) % MO;
  83. }
  84. //printf("c = %d d = %d \n", c, d);
  85. for(int i = ; (i - ) * T < MO; i++) {
  86. op = (1ll * op * c + d) % MO;
  87. int t = Hash::find(op);
  88. //printf("op = %d t = %d \n", op, t);
  89. if(t != -) {
  90. printf("%d\n", i * T - t + );
  91. return;
  92. }
  93. }
  94. printf("-1\n");
  95. return;
  96. }
  97.  
  98. int main() {
  99. int T;
  100. scanf("%d", &T);
  101. while(T--) {
  102. solve();
  103. }
  104. return ;
  105. }

AC代码

洛谷P3306 随机数生成器的更多相关文章

  1. 洛谷P3600 随机数生成器(期望dp 组合数)

    题意 题目链接 Sol 一条重要的性质:如果某个区间覆盖了另一个区间,那么该区间是没有用的(不会对最大值做出贡献) 首先不难想到枚举最终的答案\(x\).这时我们需要计算的是最大值恰好为\(x\)的概 ...

  2. [洛谷P5147]随机数生成器

    题目大意:$$f_n=\begin{cases}\frac{\sum\limits_{i=1}^nf_i}n+1&(n>1)\\0&(n=1)\end{cases}$$求$f_n ...

  3. 洛谷P3600随机数生成器——期望+DP

    原题链接 写到一半发现写不下去了... 所以orz xyz32768,您去看这篇题解吧,思路很清晰,我之前写的胡言乱语与之差距不啻天渊 #include <algorithm> #incl ...

  4. 洛谷 P3600 - 随机数生成器(期望 dp)

    题面传送门 我竟然独立搞出了这道黑题!incredible! u1s1 这题是我做题时间跨度最大的题之一-- 首先讲下我四个月前想出来的 \(n^2\log n\) 的做法吧. 记 \(f(a)=\m ...

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

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

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

    传送门 感觉我BSGS都白学了……数学渣渣好像没有一道数学题能自己想出来…… 要求$X_{i+1}=aX_i+b\ (mod \ \ p)$ 左右同时加上$\frac{b}{a-1}$,把它变成等比数 ...

  7. 洛谷 [P4035] 球形空间生成器

    高斯消元 注意浮点误差,判断一个浮点数是否为 0 的时候,看他的绝对值与 \(10^{-8}\)的关系 #include <iostream> #include <algorithm ...

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

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

  9. P3306 [SDOI2013]随机数生成器(bzoj3122)

    洛谷 bzoj 特判+多测真恶心 . \(0\le a\le P−1,0\le b\le P−1,2\le P\le 10^9\) Sample Input 3 7 1 1 3 3 7 2 2 2 0 ...

随机推荐

  1. Spring 基于Aspectj切面表达式(6)

    1 package com.proc; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinP ...

  2. 全网最全乌云drops文章下载(epub)

    前几天搞得epub格式的,为了方便kindle才做的,没想到站关了. 链接: http://pan.baidu.com/s/1eRIoJC2 密码: b6aq

  3. 记 openSUSE 42.3 升级到Leap 15.0

    先将系统的软件更新到最新版本 sudo zypper update 删除42.3的软件源,若有其他数据源,如nginx的,也需要一并删除,可使用zypper lr -d 来查询 sudo zypper ...

  4. 转载:Linux命令经典面试题:统计文件中出现次数最多的前10个单词

    1.使用linux命令或者shell实现:文件words存放英文单词,格式为每行一个英文单词(单词可以重复),统计这个文件中出现次数最多的前10个单词 主要考察对sort.uniq命令的使用,相关解释 ...

  5. 在python3中的编码

    在python3中的编码 #_author:Administrator#date:2019/10/29import sysprint(sys.getdefaultencoding())#utf-8 打 ...

  6. Sentinel 发布里程碑版本,添加集群流控功能

    自去年10月底发布GA版本后,Sentinel在近期发布了另一个里程碑版本v1.4(最新的版本号是v1.4.1),加入了开发者关注的集群流控功能. 集群流控简介 为什么要使用集群流控呢?假设我们希望给 ...

  7. &卡特兰数学习笔记

    一.关于卡特兰数 卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 20801 ...

  8. webpack引入jQuery

    1. 本地文件引入 配置 const webpack=require('webpack'); module.exports={ resolve:{ alias:{ //绝对路径 jQuery:path ...

  9. 2019/10/9 CSP-S 模拟测

    T1:最大约数和 给定一个正整数 S,现在要求你选出若干个互不相同的正整数,使得它们的和不大于 S,而且每个数的因数(不包括本身)之和最大.S <= 1000 分析: 其实考完才听他们说是背包, ...

  10. Android基础控件EditText

    1.常用属性 <!--selectAllOnFocus 获得焦点后全选组件内所有文本内容--> <!--inputType 限制输入方式--> <!--singleLin ...