【哈希和哈希表】門票

門票

時間限制: 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章