問題 I: 【雜湊和雜湊表】門票
問題 I: 【雜湊和雜湊表】門票
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 43 解決: 6
[提交] [狀態] [討論版] [命題人: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
map超時了,搜了下題解學習了下hash表,怎麼說呢,和鏈式前向星有點像,或者說鄰接表,
就是將每一項的值%一個數,獲得一個值作為一個數組的下標,如果這個出現過,用鏈式前向星或者說鄰接表
的想法去存一下,這樣找的時候相當於遍歷一個節點的鄰接表,嗯,就是這樣
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2200000,Mod = 2181271; int Hash[maxn]; struct Point{ ll val; int next; }p[maxn]; bool Count(int pos,ll x){ for(int i=Hash[pos]; i ;i = p[i].next) if(p[i].val == x) return 1; return 0; } int A,B,C; int main(){ ll a = 1; Hash[1] = p[1].val = 1; scanf("%d%d%d",&A,&B,&C); for(int i=1;i<=2000000;i++){ a = (a*A + a%B )%C; int pos = a%Mod; if(Count(pos,a)){ printf("%d\n",i); return 0; } p[i+1] = {a,Hash[pos]}; Hash[pos] = i+1; } printf("-1\n"); return 0; }