wenbao与字符串Hash

------------------------------

http://begin.lydsy.com/JudgeOnline/problem.php?id=1729

N*M字符矩阵中找出至少两个相同的正方形,要求边长尽量长 

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 #define ll long long
 6 const int maxn = 505;
 7 const ll D = 97, D2 = 131;
 8 int n, m;
 9 ll p[maxn], p2[maxn], hs[maxn*maxn], h[maxn][maxn];
10 char a[maxn][maxn];
11 
12 bool ok(int x){
13     for(int i = 1; i <= n; ++i){
14         ll tmp = 0;
15         for(int j = 1; j < x; ++j) tmp = tmp*D + a[i][j], h[i][j] = 0;
16         for(int j = x; j <= m; ++j) h[i][j] = tmp = tmp*D - p[x]*a[i][j-x] + a[i][j];
17     }
18     int num = 0;
19     for(int i = x; i <= m; ++i){
20         ll tmp = 0;
21         for(int j = 1; j < x; ++j) tmp = tmp*D2 + h[j][i];
22         for(int j = x; j <= n; ++j) hs[num++] = tmp = tmp*D2 - p2[x]*h[j-x][i] + h[j][i];
23     }
24     sort(hs, hs+num);
25     for(int i = 1; i < num; ++i) if(hs[i] == hs[i-1]) return true;
26     return false;
27 }
28 int main(){
29     scanf("%d%d", &n, &m);
30     for(int i = 1; i <= n; ++i){
31         scanf("%s", a[i]+1);
32         for(int j = 1; j <= m; ++j) a[i][j] -= 'a';
33     }
34     int l = 0, r = (n < m ? n : m), sum = 0;
35     p[0] = 1, p2[0] = 1;
36     for(int i = 1; i <= r; ++i) p[i] = p[i-1]*D, p2[i] = p2[i-1]*D2;
37     while(l <= r){
38         int mid = (l+r)>>1;
39         if(ok(mid)) sum = mid, l = mid+1;
40         else r = mid-1;
41     }
42     printf("%d
", sum);
43     return 0;
44 }

 -----------------------------------------------

http://acm.scu.edu.cn/soj/problem.action?id=4438

 1 #include <iostream>
 2 #include <string.h>
 3 using namespace std;
 4 
 5 #define ll long long
 6 const int maxn = 5e6+10;
 7 char str[maxn], ss[maxn], st[maxn];
 8 ll p, D = 97, a[maxn];
 9 
10 int main(){
11     while(~scanf("%s%s", str, ss)){
12         ll aim = 0;
13         p = 1;
14         int len1 = strlen(str), len2 = strlen(ss);
15         for(int i = 0; i < len1; ++i){
16             aim = aim*D + str[i]-'a';
17             p *= D;
18         }
19         ll tmp = 0;
20         int top = 0;
21         for(int i = 0; i < len2; ++i){
22             st[top] = ss[i];
23             tmp = tmp*D + ss[i] - 'a';
24             a[++top] = tmp;
25             if(top >= len1 && tmp - a[top-len1]*p == aim){
26                 //cout<<i<<"***"<<endl;
27                 tmp = a[top-len1];
28                 top -= len1;
29             }
30         }
31         st[top] = '';
32         printf("%s
", st);
33     }
34     return 0;
35 }

 --------------------------------------------

只有不断学习才能进步!

原文地址:https://www.cnblogs.com/wenbao/p/7444748.html