首先:得感谢我的队友,因为我之前在赶课设,完全没有去补题,神雕侠侣,我是其中的雕
题意:将n个字符串输入,然后求s[i]的前缀和s[j]的后缀匹配的最大长度,平方,求和
思考:补这道题可谓是经历了九九八十一难,显示自己一直在怀疑自己题目意思是否看懂,结果发现自己的确没有理解题意,然后多亏了群巨暮雨忽来的帮助,我理解了题目的意思,只有确认了,自己字符串操作已经是傻逼了,只能重新把之前的字符串的KMP,hash,trie和AC自动机全部重新看一遍,看前面三个一小时,AC自动机看了一上午都没有整明白,真的是废了(之前也没有整明白)
整完之后AC自动机整了半天,自己的思路是将所有的字符串进行建立trie图,注意以为节点建立fail,然后不断一个一个枚举最大长度,结论:还是不行
最后再刘小哥哥的思路之下开拓了,直接就是将所以的字符串进行hash,然后不断的进行存入map数组中,之后统计每个字符串的前缀在map中出现的次数。
因为考虑到去重,需要将每个字符串的next数组给求出来,然后减去就可以了,代码如下(参考的,之后自己搞一搞AC自动机做法,群巨推荐),为了赶时间,临时补一下:
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#define rep(i,a,b) for(int i = a; i <= b ; i ++ )
#define pre(i,a,b) for(int i = b ; i >= a ; i --)
#define ll long long
#define inf 0x3f3f3f3f
#define ull unsigned long long
#define ios ios::sync_with_stdio(false),cin.tie(0)
using namespace std;
typedef pair<int,int> PII ;
const int N=2e6+10,mod=998244353,p=233;
string s[N];
string T;
ull Hash[N];
ull pp[N];
map<ull, ull> mmap;
ull cnt[N];
int ne[N];
int slen, tlen;
void getnext()
{
int j, k;
j = 0;
k = -1;
ne[0] = -1;
while(j < tlen)
{
if(k == -1 || T[j] == T[k])
ne[++j] = ++k;
else
k = ne[k];
}
}
bool kmp(char *s,char *p)
{
int m=strlen(s);
int n=strlen(p);
for(int i=0,j=-1; i<=m; i++)
{
while(j && s[i]!=p[j+1])
{
j=ne[j];
}
if(s[i]==p[j+1])
{
j++;
}
if(j==n) //匹配成功
{
return true;
}
}
return false;
}
int main(int argc, char const *argv[])
{
ios;
int n;
scanf("%d", &n);
pp[0] = 1;
for(int i = 1; i < N; i++)
{
pp[i] = 1ll * pp[i - 1] * p % mod;
}
for(int i = 1; i <= n; i++)
{
cin >> s[i];
int len = s[i].size();
ull base = 1;
ull hs = 0;
for(int j = len - 1; j >= 0; --j)
{
hs += base * s[i][j];
mmap[hs]++;
base *= p;
}
}
ull ans = 0;
for(int i = 1; i <= n; i++)
{
T = s[i];
tlen = T.size();
ull hs = 0;
for(int j = 0; j < tlen; j++)
{
cnt[j] = 0;
hs = hs * p + s[i][j];
if(!mmap.count(hs))
continue;
cnt[j] += mmap[hs];
}
getnext();
for(int j = 1; j <= tlen; j++)
{
if(ne[j] == 0)
continue;
cnt[ne[j] - 1] -= cnt[j - 1];
}
for(int j = 0; j < tlen; j++)
{
ans = (ans + 1ll * (j + 1) * (j + 1) % mod * cnt[j] % mod) % mod;
}
}
cout << ans << endl;
return 0;
}
൘㘳㲁৫䟽ˈ∄ྲєњ “aba”ˈަѝՊᴹєњࡽ㔰 “a”, “aba” 㻛㇇ࡠˈնᇎ䱵кਚᓄ䈕
ਆ “aba” 㘼нᱟ “a”DŽ