The hash in algorithm competition is a magic algorithm which is often all kinds of probability / metaphysics but is quick and convenient
The essence is to reduce the weight of the data by establishing a unique mapping of the target data, which can often confuse some problems
hash to circular array
Solution idea: find the minimum representation for each six tuple, map the double hash corresponding to the product and sum into a linked list, and then judge
String hash
https://www.acwing.com/problem/content/140/ Substring hash template problem
http://www.51nod.com/Challenge/Problem.html#!#problemId=1089 hash O(n) algorithm of longest palindrome substring
You don't have to remember horse drawn cars anymore 233
Solution: String hash often uses the base conversion method, which has the property of class prefix sum
ull pre[MAXN], fac[MAXN] = {1}; //Natural spillover method cin >> s + 1 for(int i = 1; i <= len; ++i) //Create hash table { fac[i] = fac[i - 1] * P; pre[i] = pre[i - 1] * P + s[i]; } ull getprehash(int a, int b) //Query hash value of any string { return pre[b] - pre[a - 1] * fac[b - a + 1]; }
hash method of the longest palindrome substring
/* Zeolim - An AC a day keeps the bug away */ //pragma GCC optimize(2) #include <cstdio> #include <iostream> #include <cstdlib> #include <cmath> #include <cctype> #include <string> #include <cstring> #include <algorithm> #include <stack> #include <queue> #include <set> #include <sstream> #include <map> #include <ctime> #include <vector> #include <fstream> #include <list> #include <iomanip> #include <numeric> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const ld PI = acos(-1.0); const ld E = exp(1.0); const int INF = 0x3f3f3f3f; const int MAXN = 1e6 + 10; const ll MOD = 1e9 + 7; const ull P = 131; ull pre[MAXN], fac[MAXN] = {1}, pio[MAXN]; char s[MAXN]; ull getprehash(int a, int b) { return pre[b] - pre[a - 1] * fac[b - a + 1]; } ull getpiohash(int a, int b) { return pio[a] - pio[b + 1] * fac[b - a + 1]; } int main() { //ios::sync_with_stdio(false); //cin.tie(0); cout.tie(0); //freopen("D://test.in", "r", stdin); //freopen("D://test.out", "w", stdout); int flag = 1; while(cin >> s + 1) { if(s[1] == 'E' && s[2] == 'N' && s[3] == 'D') break; int len = strlen(s + 1); pio[len + 1] = 1; int ans = 1, pis = 0, apis = 0; for(int i = 1; i <= len; ++i) { fac[i] = fac[i - 1] * P; pre[i] = pre[i - 1] * P + s[i]; } for(int i = len; i >= 1; --i) { pio[i] = pio[i + 1] * P + s[i]; } for(int i = 1; i <= len; ++i) { int rpis = pis + 1; while(i - rpis >= 1 && i + rpis <= len && getprehash(i - rpis, i) == getpiohash(i, i + rpis)) { ans = max(ans, rpis * 2 + 1), pis = rpis, ++rpis; } rpis = apis; while(i + 1 - rpis >= 1 && i + rpis <= len && getprehash(i - rpis + 1, i + 1) == getpiohash(i, i + rpis)) { ans = max(ans, rpis * 2), apis = rpis, ++rpis; } } cout << ans << '\n'; } return 0; }