【哈希和哈希表】门票

门票

时间限制: 1 Sec  内存限制: 128 MB
提交: 26  解决: 2
[提交] [状态] [讨论版] [命题人:admin]

题目描述

RPK要带MSH去一个更加神秘的地方!
RPK带着MSH穿过广场,在第1618块砖上按下了一个按钮,在一面墙上随即出现了一个把手。RPK握住把手,打开了一扇石质大门。他们穿过悠长而芬芳的小道,走到了一扇象征时间的大门――“the gate of time”。
门上写着一个关于时间的谜题“承诺:____年”,RPK思考了一会,从容地用手指写下1万,这时,门开始发出闪光,MSH感觉到自己的心跳都快停止了。
门开了,眼前是一座美丽的神秘花园!
正当RPK和MSH准备进入的时候,突然出现了一个看门的老大爷QL。
QL:“你们干什么你们,还没买票呢!”
RPK突然想起来现金全拿去买蛋糕了,RPK很绅士的问:“能刷卡么?我身上没现金。”
QL:“没钱?那你们不能进去!”
RPK(汗):“……”
QL:“等等,我这有道不会的数学题,你解了我就让你们进去。”
(众人:“……”)
有一个数列{an},a0=1,ai+1=(A*ai+ai mod B)mod C,要求这个数列第一次出现重复的项的标号。
这点小问题当然难不倒数学bug男RPK了,仅凭心算他就得到了结果。

 

输入

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

 

输出

输出第一次出现重复项的位置,如果答案超过2000000 输出-1

 

样例输入

2 2 9

 

样例输出

4

 

提示

30%的数据A B C≤105
100%的数据 A B C≤109

试过set暴力,结果跑到90000左右的数据就T了,求教大佬之后才知道是用哈希做,建哈希表,选个适合的质数取模哈希,再暴力跑即可

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2200000;
const int modd = 2181271;
int hashh[maxn];
struct z
{
    int nextt,v;
}z[maxn];
bool countt(int tmp, int tmpp)
{
    for (int i = hashh[tmpp]; i; i = z[i].nextt)
        if (tmp == z[i].v)
            return 1;
    return 0;
}
int main()
{
//    freopen("in.txt", "r", stdin);
    int a,b,c;
    scanf("%d%d%d", &a, &b, &c);
    hashh[1] = z[1].v = 1;
    int tmp = 1;
    for (int i = 1; i <= 2000000; i++)
    {
        tmp = ((ll) a * tmp + tmp % b) % c;
        int tmpp = tmp % modd;
        if (countt(tmp, tmpp))
        {
            printf("%d\n", i);
            return 0;
        }
        z[i + 1].v = tmp;
        z[i + 1].nextt = hashh[tmpp];
        hashh[tmpp] = i + 1;
    }
    puts("-1");
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值