题意
给出一个模板串和n个字符串,设每个字符串的权值为其字串中模板串前缀的长度,求n个字符串中最大权值和。
题解
前置知识:kmp
使用kmp的next数组即可,在两串匹配过程中不断更新j指针能在模板串中到达的最远位置,即为能匹配的最长前缀。将n个字符串逐个匹配取最大值加和即可。
code
#include <bits/stdc++.h>
#define reg register
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
#define e exp(1.0)
#define ios ios::sync_with_stdio(false)
#define rep(i,l,r) for(int i=(l);i<(r);i++)
using namespace std;
const int maxn = 2e5 + 10;
const int mod = 1e9 + 7;
int nxt[maxn];
void getnxt(string p)
{
nxt[0] = -1;
int i = 0, j = -1;
while(i < p.size()){
if(j == -1 || p[i] == p[j]){
j++;
i++;
nxt[i] = j;
}
else j = nxt[j];
}
}
int kmp(string a, string p)
{
int mx = 0;
getnxt(p);
int i = 0,j = 0;
while(i < (int)a.size() && j < (int)p.size()){
if(j == -1 || a[i] == p[j]){
i++;
j++;
mx = max(mx,j);
}
else j = nxt[j];
}
return mx;
}
int main()
{
string s;
cin>>s;
getnxt(s);
int n;
cin>>n;
ll res = 0;
for(int i = 0; i < n;++i){
string p;
cin>>p;
res += 1ll * kmp(p,s);
}
cout<<res<<endl;
return 0;
} 
京公网安备 11010502036488号