Hash

题意:

对于字符串哈希中的$H(i) =  a*H(i-1) + (S[i]-'a'+1)  mod \  b$给出a,b求出100个hash值相同的串。

 

解法:

概率论上有一经典模型:选出100个人生日不同的概率:

有$$P(没有人生日相同) = \frac{A_{365}^{100}}{{365}^{100}} \approx 0.00000031$$

从而可以认为100%能找到。

这样我们随机100000个长度为7的字符串,可以认为100%能找到一对hash值相同,记做S0,S1

这样我们将7个S0或者S1接起来,就得到了128个串。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <map>
 6 
 7 #define LL long long
 8 
 9 using namespace std; 
10 
11 int a,b,tot;
12 string S0,S1;
13 int v[7];
14 map<LL,string> mp;
15 
16 bool Print(int t)
17 {
18     if(tot==100) return 1;
19     if(t==7)
20     {
21         tot++;
22         for(int i=0;i<7;i++)
23         {
24             if(v[i]==0) cout<<S0;
25             else cout<<S1;
26         }
27         cout<<endl;
28         return tot==100;
29     }
30     v[t]=0;
31     if(Print(t+1)) return 1;
32     v[t]=1;
33     if(Print(t+1)) return 1;
34     return 0;
35 }
36 
37 void Random(string &S)
38 {
39     S.clear();
40     for(int i=0;i<7;i++)
41         S.push_back(rand()%26+'a');
42 }
43 
44 LL calc(const string &S)
45 {
46     LL ans=0;
47     for(int i=0;i<7;i++)
48         ans = (ans*(LL)a + (S[i]-'a'+1LL))%(LL)b;
49     return ans;
50 }
51 
52 int main()
53 {
54     srand(577555);
55     cin>>a>>b;
56     mp.clear();
57     while(1)
58     {
59         Random(S1);
60         LL tmp=calc(S1);
61         if(mp.count(tmp) && S1!=mp[tmp])
62         {
63             S0=mp[tmp];
64             break;
65         }
66         mp[tmp]=S1;
67     }
68     Print(0);
69     return 0;
70 }
View Code

 

posted @ 2017-03-11 21:59  lawyer'  阅读(122)  评论(0编辑  收藏  举报