参考博客 https://www.cnblogs.com/henry-1202/p/8868414.html
hash可以解决很多有趣的问题例如kmp,ac自动机,马拉车,后缀数组等等
一个很大的质数ull mod = 212370440130137957ll;
基础练习hash
题目链接https://www.acwing.com/problem/content/description/140/
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 23333;
using namespace std;
unordered_map<ll,ll> ss;
char a[maxn];
ull h[maxn];
ull f[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> (a + 1);
ll n = strlen(a + 1);
f[0] = 1;
for(int i = 1; i <= n; i ++)
{
h[i] = h[i - 1] * base + (a[i] - '0');
f[i] = f[i - 1] * base;
}
ll t;
cin >> t;
while(t--)
{
ll a,b,l,r;
cin >> a >> b >> l >> r;
if(h[b] - h[a - 1] * f[b - a + 1] == h[r] - h[l - 1] * f[r - l + 1])
{
cout << "Yes" << "\n";
}
else
{
cout << "No" << "\n";
}
}
return 0;
}
模式匹配 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1686
ac代码如下
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 233333;
using namespace std;
char a[maxn];
char b[maxn];
ull h1[maxn],f[maxn],h2[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll t;
cin >> t;
while(t--)
{
cin >> (a + 1);
ll n = strlen(a + 1);
cin >> (b + 1);
ll m = strlen(b + 1);
for(int i = 1; i <= n; i ++)
{
h1[i] = h1[i - 1] * base + (a[i] - '0');
}
f[0] = 1;
for(int i = 1; i <= m; i ++)
{
h2[i] = h2[i - 1] * base + (b[i] - '0');
f[i] = f[i - 1] * base;
}
ll ans = 0;
for(int i = 1; i + n - 1 <= m; i ++)
{
ll r = i + n - 1;
if(h2[r] - h2[i - 1] * f[r - i + 1] == h1[n])
{
ans ++;
}
}
cout << ans << endl;
}
return 0;
}
雪花问题求出最小匹配
题目链接https://www.acwing.com/problem/content/description/139/
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll maxn = 1e5 + 7;
const ll mod = 1e9 + 7;
const ull base = 23333;
using namespace std;
unordered_map<ll,ll> ss;
ll check(ll now,ll com,vector<ll> a)
{
ll n = a.size();
for(int i = 0; i < a.size(); i ++)
{
if(a[(now + i) % n] != a[(com + i) % n])
return a[(now + i) % n] < a[(com + i) % n];
}
return 0;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll n;
cin >> n;
for(int i = 1; i <= n; i ++)
{
ll x;
vector<ll>a,b,c;
for(int j = 1; j <= 6; j ++)
{
cin >> x;
a.push_back(x);
}
ll ans = 0;
for(int j = 1; j < 6; j ++)
{
if(check(ans,j,a))ans = j;
}
for(int j = 0; j < 6; j ++)
{
b.push_back(a[(ans + j) % 6]);
}
reverse(a.begin(),a.end());
ans = 0;
for(int j = 1; j < 6; j ++)
{
if(check(ans,j,a))ans = j;
}
for(int j = 0; j < 6; j ++)
{
c.push_back(a[(ans + j) % 6]);
}
ll be = 1;
for(int j = 0; j < 6; j ++)
{
if(b[j] != c[j])
{
if(b[j] < c[j])
{
be = 1;
break;
}
else
{
be = 2;
break;
}
}
}
if(be == 1)
{
ull ans = 0;
for(int j = 0; j < b.size(); j ++)
{
ans = ans * base + b[j];
}
if(ss[ans] == 1)
{
cout << "Twin snowflakes found." << endl;
return 0;
}
ss[ans] = 1;
}
else
{
ull ans = 0;
for(int j = 0; j < c.size(); j ++)
{
ans = ans * base + c[j];
}
if(ss[ans] == 1)
{
cout << "Twin snowflakes found." << endl;
return 0;
}
ss[ans] = 1;
}
}
cout << "No two snowflakes are alike." << endl;
return 0;
}
运用前缀 题目链接https://loj.ac/problem/2823
ac代码如下
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll maxn = 2e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 131;
using namespace std;
char a[maxn];
char b[maxn];
ull h[maxn],f[maxn];
ll get_hash(ll l,ll r)
{
return h[r] - h[l - 1] * f[r - l + 1];
}
ll get_s(ll l,ll r,ll x)
{
return get_hash(l,x - 1) * f[r - x] + get_hash(x + 1,r);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
set<ll>s;
ll n;
cin >> n;
cin >> (a + 1);
if(n % 2 == 0)
{
cout << "NOT POSSIBLE" << endl;
}
else
{
f[0] = 1;
for(int i = 1; i <= n; i ++)
{
f[i] = f[i - 1] * base;
h[i] = h[i - 1] * base + a[i];
}
ll pre,nxt,mark = 0;
for(int i = 1; i <= n; i ++)
{
if(i <= n / 2)
pre = get_s(1,n / 2 + 1,i);
else
pre = h[n / 2];
if(i <= n / 2 + 1)
nxt = get_hash(n / 2 + 2,n);
else
nxt = get_s(n / 2 + 1,n,i);
if(pre == nxt)
{
mark = i;
s.insert(pre);
}
}
if(s.empty())
{
cout << "NOT POSSIBLE" << endl;
}
else
{
if(s.size() > 1)
{
cout << "NOT UNIQUE" << endl;
return 0;
}
if(s.size() == 1)
{
if(mark <= n / 2)
{
for(int i = 1; i <= n / 2 + 1; i ++)
{
if(i != mark)
{
cout << a[i];
}
}
cout << endl;
}
else
{
for(int i = n / 2 + 1; i <= n; i ++)
{
if(i != mark)
{
cout << a[i];
}
}
cout << endl;
}
}
}
}
return 0;
}
马拉车题目链接https://www.51nod.com/Challenge/Problem.html#!#problemId=1089
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll maxn = 1e6 + 7;
const ll mod = 1e9 + 7;
const ull base = 233333;
using namespace std;
char a[maxn];
ull h1[maxn],f[maxn],h2[maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
//freopen("E://1.txt","r",stdin);
cin >> (a + 1);
ll n = strlen(a + 1);
f[0] = 1;
for(int i = 1; i <= n; i ++)
{
h1[i] = h1[i - 1] * base + (a[i] - '0');
f[i] = f[i - 1] * base;
}
for(int i = n; i >= 1; i --)
{
h2[i] = h2[i + 1] * base + (a[i] - '0');
}
ll ma = 1;
for(int i = 1; i <= n; i ++)
{
if(a[i] == a[i + 1])
{
ll l1 = i;
ll r1 = i - ma / 2 + 1;
ll l2 = i + 1;
ll r2 = i + 1 + ma / 2 - 1;
ma = max(ma,(ll)2);
while(r1 >= 1 && r2 <= n && h1[l1] - h1[r1 - 1] * f[l1 - r1 + 1] == h2[l2] - h2[r2 + 1] * f[r2 - l2 + 1])
{
ma = max(ma,r2 - r1 + 1);
r1 --;
r2 ++;
}
}
if(a[i - 1] == a[i + 1])
{
ll l1 = i - 1;
ll r1 = i - 1 - ma / 2 + 1;
ll l2 = i + 1;
ll r2 = i + 1 + ma / 2 - 1;
ma = max(ma,(ll)3);
while(r1 >= 1 && r2 <= n && h1[l1] - h1[r1 - 1] * f[l1 - r1 + 1] == h2[l2] - h2[r2 + 1] * f[r2 - l2 + 1])
{
ma = max(ma,r2 - r1 + 1);
r1 --;
r2 ++;
}
}
}
cout << ma << endl;
return 0;
}