题目
赛时没想到hash O ( 1 ) O(1) O(1)判断
枚举S1,二分S2长度,利用Hash判断两字符串相等。
代码
AC代码:
/*
* @Author: hesorchen
* @Date: 2020-11-26 09:12:46
* @LastEditTime: 2021-02-21 16:19:05
* @Description: 栽种绝处的花
*/
#include <bits/stdc++.h>
using namespace std;
const unsigned long long base = 13331;
unsigned long long pre_pow[100010];
string a, b;
int len1, len2;
void pre()
{
len1 = a.size(), len2 = b.size();
a = ' ' + a;
b = ' ' + b;
pre_pow[0] = 1;
for (int i = 1; i <= 100000; i++)
pre_pow[i] = pre_pow[i - 1] * base;
}
unsigned long long Hasha[100010], Hashb[100010], ans;
void gethash()
{
for (int i = 1; i <= len1; i++)
Hasha[i] = Hasha[i - 1] * base + a[i];
for (int i = 1; i <= len2; i++)
Hashb[i] = Hashb[i - 1] * base + b[i];
}
bool check(int s1, int s2)
{
unsigned long long res1 = Hasha[s1] * pre_pow[s2];
unsigned long long res2 = Hasha[s2];
unsigned long long res3 = res1 + res2;
if (res3 == Hashb[s1 + s2])
return true;
return false;
}
void getans()
{
for (int i = 1; i <= len1; i++)
{
if (i < len2 && Hasha[i] == Hashb[i] && a[1] == b[i + 1])
{
int l = 1, r = len2 - i, res = 0;
while (l <= r)
{
int mid = l + r >> 1;
if (check(i, mid))
{
l = mid + 1;
res = mid;
}
else
r = mid - 1;
}
ans += res;
}
}
}
int main()
{
cin >> a >> b;
pre();
gethash();
getans();
cout << ans << endl;
return 0;
}
双哈希代码(练习):
/*
* @Author: hesorchen
* @Date: 2020-11-26 09:12:46
* @LastEditTime: 2021-02-21 16:26:34
* @Description: 栽种绝处的花
*/
#include <bits/stdc++.h>
using namespace std;
const unsigned long long base = 13331, base2 = 1331;
unsigned long long pre_pow[100010];
unsigned long long pre_pow2[100010];
unsigned long long Hasha[100010], Hashb[100010], ans;
unsigned long long Hasha2[100010], Hashb2[100010];
string a, b;
int len1, len2;
void pre()
{
len1 = a.size(), len2 = b.size();
a = ' ' + a;
b = ' ' + b;
pre_pow[0] = 1;
for (int i = 1; i <= 100000; i++)
pre_pow[i] = pre_pow[i - 1] * base;
pre_pow2[0] = 1;
for (int i = 1; i <= 100000; i++)
pre_pow2[i] = pre_pow2[i - 1] * base2;
}
void gethash()
{
for (int i = 1; i <= len1; i++)
Hasha[i] = Hasha[i - 1] * base + a[i];
for (int i = 1; i <= len2; i++)
Hashb[i] = Hashb[i - 1] * base + b[i];
for (int i = 1; i <= len1; i++)
Hasha2[i] = Hasha2[i - 1] * base2 + a[i];
for (int i = 1; i <= len2; i++)
Hashb2[i] = Hashb2[i - 1] * base2 + b[i];
}
bool check(int s1, int s2)
{
int flag1 = 0, flag2 = 0;
unsigned long long res1 = Hasha[s1] * pre_pow[s2];
unsigned long long res2 = Hasha[s2];
unsigned long long res3 = res1 + res2;
if (res3 == Hashb[s1 + s2])
flag1 = 1;
res1 = Hasha2[s1] * pre_pow2[s2];
res2 = Hasha2[s2];
res3 = res1 + res2;
if (res3 == Hashb2[s1 + s2])
flag2 = 1;
return (flag1 && flag2);
}
void getans()
{
for (int i = 1; i <= len1; i++)
{
if (i < len2 && Hasha[i] == Hashb[i] && Hasha2[i] == Hashb2[i] && a[1] == b[i + 1])
{
int l = 1, r = len2 - i, res = 0;
while (l <= r)
{
int mid = l + r >> 1;
if (check(i, mid))
{
l = mid + 1;
res = mid;
}
else
r = mid - 1;
}
ans += res;
}
}
}
int main()
{
cin >> a >> b;
pre();
gethash();
getans();
cout << ans << endl;
return 0;
}