1. 程式人生 > >問題 I: 【雜湊和雜湊表】門票

問題 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;
}