#10041 「一本通 2.1 练习 7」门票

题目描述

RPK 带着 MSH 穿过广场,在第 1618 块砖上按下了一个按钮,在一面墙上随即出现了一个把手。RPK 握住把手,打开了一扇石质大门。他们穿过悠长而芬芳的小道,走到了一扇象征时间的大门——“the gate of time”。
门上写着一个关于时间的谜题 “承诺:____ 年”,RPK 思考了一会,从容地用手指写下 1 万,这时,门开始发出闪光,MSH 感觉到自己的心跳都快停止了。
门开了,眼前是一座美丽的神秘花园!

正当 RPK 和 MSH 准备进入的时候,突然出现了一个看门的老大爷 QL。
QL:“你们干什么你们,还没买票呢!”
RPK 突然想起来现金全拿去买蛋糕了,RPK 很绅士的问:“能刷卡么?我身上没现金。”
QL:“没钱?那你们不能进去!”
RPK(汗):“……”
QL:“等等,我这有道不会的数学题,你解了我就让你们进去。”
(众人:“……”)

有一个数列 \{a_n\}, a_0 = 1, a_{i+1} = (A\times{a_i} + a_i \bmod B) \bmod C,要求这个数列第一次出现重复的项的标号。

这点小问题当然难不倒数学 bug 男 RPK 了,仅凭心算他就得到了结果。

输入格式

一行三个数,分别表示 A, B, C。

输出格式

输出第一次出现重复项的位置,如果答案超过 2\times 10^6 输出 -1。

样例

输入

2 2 9

输出

4

数据范围与提示

30% 的数据 A , B , C ≤ 1 0 5 A, B, C \le { 10^5 } A,B,C105

100% 的数据 A , B , C ≤ 1 0 9 A, B, C \le { 10^9 } A,B,C109

30% 的数据 空间限制 4 M 4\text{M} 4M。(囿于测评系统的实现,这部分的空间限制取消)

大致思路

虽说是一个哈希表的题,但完全可以用unordered_map水过去
具体思路也很简单,有就打标记,有重复直接break;

#include
#define ull unsigned long long 
using namespace std;
long long int a,b,c,ans;
bool flag=1;
ull k;
/*unordered_*/map<ull,bool>mapp;
int main(){
	cin>>a>>b>>c;
	k=1;ans=0;mapp[1]=1;
	while(flag){
		ans++;
		if(ans>2000000){
			cout<<-1<<endl;
			break;
		}
		k=(a*k+k%b)%c;
		if(mapp[k]==1){
		cout<<ans<<endl;
			break;
		}
		mapp[k]=1;
	}
	return 0;
}

纯暴力代码,居然也能过

#include
#define maxn 66000000
#define LL long long
#define uLL unsigned long long
using namespace std;
int A,B,C,cnt;
uLL Get[maxn];
bool vis[maxn];
int main(){
	cin>>A>>B>>C;
	Get[0]=1;vis[1]=1;
	while(1){
		cnt++;
		Get[cnt]=(Get[cnt-1]*A+Get[cnt-1]%B)%C;
		if(cnt>2e6) {
			cout<<"-1";
			return 0;
		}
		if(vis[Get[cnt]]) break;
		vis[Get[cnt]]=1;
	}
	cout<<cnt;
	
	return 0;
}

附封面

#10041 「一本通 2.1 练习 7」门票_第1张图片

你可能感兴趣的:(算法)