博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3306 随机数生成器
阅读量:6885 次
发布时间:2019-06-27

本文共 2787 字,大约阅读时间需要 9 分钟。

题意:给你一个数列,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 
2 3 const int N = 100010; 4 5 int MO, A, B, op, aim; 6 7 inline int qpow(int a, int b) { 8 int ans = 1; 9 while(b) { 10 if(b & 1) { 11 ans = 1ll * ans * a % MO; 12 } 13 a = 1ll * a * a % MO; 14 b = b >> 1; 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 = 999983; 24 int e[mod]; 25 inline void clear() { 26 tp = 0; 27 memset(e, 0, 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 -1; 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", 1); 60 return; 61 } 62 if(A == 0) { 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 = 0; 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 == 1) { 79 d = 1ll * B * T % MO; 80 } 81 else { 82 d = (1ll * (c - 1) * qpow(A - 1, MO - 2) % MO * B % MO + MO) % MO; 83 } 84 //printf("c = %d d = %d \n", c, d); 85 for(int i = 1; (i - 1) * 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 != -1) { 90 printf("%d\n", i * T - t + 1); 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 0;105 }
AC代码

 

转载于:https://www.cnblogs.com/huyufeifei/p/10824307.html

你可能感兴趣的文章
2. ASIHttpRequest-发送数据
查看>>
[应用模板]移动应用界面
查看>>
嵌入式Linux C编程 02
查看>>
sql server支持连接管理功能
查看>>
java的强制类型转换想到的
查看>>
简要介绍cookie与session的区别与联系
查看>>
mysql flush用法
查看>>
response.setHeader()的用法
查看>>
一位前辈的经验,给正在思考的自己
查看>>
分享一篇关于lucene原理的文章
查看>>
基于 HTML5 结合互联网+ 的 3D 隧道
查看>>
Win10下 80端口被system(pid=4)占用的解决方法
查看>>
使用SubVersion+TortoiseSVN多仓库方式进行版本控制
查看>>
Nginx虚拟目录alias和root目录
查看>>
MySQL(Extends)
查看>>
Android KeyboardView实现App内置键盘开发
查看>>
Python文件夹复制
查看>>
细谈 vue 核心- vdom 篇
查看>>
ajax+springmvc实现跨域请求
查看>>
SaltStack快速入门-配置管理
查看>>