题目链接:点击这里
题目大意:
给出两个字符串
s
s
s 、
t
t
t ,求有多少对
s
s
s 的非空前缀连起来是
t
t
t 的前缀
题目分析:
我们可以先枚举
t
t
t 的每一个位置
如果
s
[
i
]
≠
t
[
i
]
s[i]\not=t[i]
s[i]=t[i] 显然用
s
s
s 的前
i
i
i 个字符不可能凑成
t
t
t 的一个子串(因为
s
[
i
]
s[i]
s[i] 和
t
[
i
]
t[i]
t[i] 不同)
如果
s
[
i
]
=
t
[
i
]
s[i]=t[i]
s[i]=t[i] 我们可以二分来找用
s
.
s
u
b
s
t
r
(
1
,
i
)
s.substr(1,i)
s.substr(1,i) 和其子串能构成
t
t
t 的子串的方案数,具体方法如下:
前
i
i
i 位
s
s
s 与
t
t
t 相同,之后再用哈希判断
s
.
s
u
b
s
t
r
(
1
,
i
)
s.substr(1,i)
s.substr(1,i) 的子串是否可以继续匹配,此题我使用了双哈希
具体细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#define ll long long
#define ull unsigned ll
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
//#define int ll
using namespace std;
int read()
{
int res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 1e5+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
const int base = 131;
const int base2 = 233;
int n,m,a[maxn<<2];
char s[maxn],t[maxn];
ull sum1[maxn],sum2[maxn],pre1[maxn],pre2[maxn],p[maxn],p2[maxn];
pair<ull,ull> get_hash(int l,int r,ull a[],ull b[])
{
return make_pair(a[r]-a[l-1]*p[r-l+1],(b[r]-b[l-1]*p2[r-l+1]%mod+mod)%mod);
}
signed main()
{
scanf("%s%s",s+1,t+1);
int len1 = strlen(s+1),len2 = strlen(t+1);
p[0] = 1,p2[0] = 1;
for(int i = 1;i <= max(len1,len2);i++) p[i] = p[i-1]*base,p2[i] = p2[i-1]*base2%mod;
for(int i = 1;i <= len1;i++) sum1[i] = sum1[i-1]*base+s[i],pre1[i] = (pre1[i-1]*base2+s[i])%mod;
for(int i = 1;i <= len2;i++) sum2[i] = sum2[i-1]*base+t[i],pre2[i] = (pre2[i-1]*base2+t[i])%mod;
ll ans = 0;
for(int i = 1;i <= min(len1,len2-1);i++)
{
if(s[i] != t[i]) break;
int l = 0,r = len2-i,res = 0;
while(r-l >= 0)
{
int mid = l+r>>1;
if(get_hash(1,mid,sum1,pre1) == get_hash(i+1,i+mid,sum2,pre2)) l = mid+1,res = mid;
else r = mid-1;
}
ans += res;
}
printf("%lld\n",ans);
return 0;
}