题目描述
RPK 要带 MSH 去一个更加神秘的地方!
RPK 带着 MSH 穿过广场,在第 1618 块砖上按下了一个按钮,在一面墙上随即 出现了一个把手。RPK 握住把手,打开了一扇石质大门。他们穿过悠长而芬芳的 小道,走到了一扇象征时间的大门——“ t h e the the g a t e gate gate o f of of t i m e time time”。
门上写着一个关于时间的谜题 “承诺:__ 年”,RPK 思考了一会,从容地用手 指写下 1 万,这时,门开始发出闪光,MSH 感觉到自己的心跳都快停止了。 门开了,眼前是一座美丽的神秘花园!
正当 RPK 和 MSH 准备进入的时候,突然出现了一个看门的老大爷 QL。
QL:“你们干什么你们,还没买票呢!”
RPK 突然想起来现金全拿去买蛋糕了,RPK 很绅士的问:“能刷卡么?我身上没 现金。”
QL:“没钱?那你们不能进去!”
RPK(汗):“……”
QL:“等等,我这有道不会的数学题,你解了我就让你们进去。”
(众人:“……”)
有一个数列 { a n a_n an}, a 0 a_0 a0=1, a i a_i ai+1=(A× a i a_i ai+ a i a_i ai mod B)mod C,要求这个数列第一次出现 重复的项的标号。
这点小问题当然难不倒数学 bug 男 RPK 了,仅凭心算他就得到了结果。
输入
一行三个数,分别表示 A,B,C。
输出
输出第一次出现重复项的位置,如果答案超过 2× 1 0 6 10^6 106输出 −1。
样例输入
2 2 9
样例输出
4
提示
【数据规模】
30% 的数据 A,B,C≤ 1 0 5 10^5 105;
100% 的数据 A,B,C≤ 1 0 9 10^9 109 。
题解
这个题我最开始是用的暴力,纯纯的暴力,大家应该都会打这个暴力,然后可能数据比较水,居然得了90分。后来才发现这个题是用哈希做的,我自己说不太清楚,可以看看这个链接第2部分 字符串算法(提高篇)–第1章 哈希和哈希表1463:门票
然后我们就上代码吧。
代码
#include<iostream>
#include<cstdio>
#define maxn 2200010
#define mo 2181271
using namespace std;
int hash[maxn];
struct pt{long long val;int nt;
}p[maxn];
inline bool ct(int x,long long y){for(int i=hash[x];i;i=p[i].nt)if(p[i].val==y)return 1;return 0;
}
int A,B,C;
int main(){long long a=1;p[1].val=1;hash[1]=1;scanf("%d%d%d",&A,&B,&C);for(int i=1;i<=2000000;i++){a=(a*A+a%B)%C;int x=a%mo;if(ct(x,a)){printf("%d\n",i);return 0;}p[i+1].val=a;p[i+1].nt=hash[x];hash[x]=i+1;}printf("-1\n");return 0;
}