#include <iostream>
#include <cstring>
#include <cstdio>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
using ll = long long ;
using ull = unsigned long long int ;
#define rep(i,a,b) for(int i = a; i <= b;i++)
#define nrep(i,a,b) for(int i = a; i >= b; i--)
template<typename Tp = int>
Tp read() {
Tp ans = 0; bool flag = true;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') flag = false ;
ch=getchar();
}
while(isdigit(ch)) {
ans = (ans<<3)+(ans<<1)+(ch^48) ;
ch = getchar();
}
return flag?ans:-ans ;
}
template<ll P,ll mod>
struct HASH {
vector<ll>u,p;
HASH(string &s):u(s.size()+2),p(s.size()+2){
u[0]=1;
p[0]=1;
p[0]=s[0];
for(int i=1;i<s.size();i++){
u[i]=u[i-1]*P;
p[i]=p[i-1]*P+s[i];
if(u[i]>=mod)u[i]%=mod;
if(p[i]>=mod)p[i]%=mod;
}
}
ll get(int l,int r){
return ((p[r]-p[l-1]*u[r-l+1]%mod)%mod+mod)%mod;
}
};
const int N = 3e5+10 ;
char ss[N];
void solve() {
int n=read();
map<pair<ull,ull>,int>mp;
for(int ii=0;ii<n;ii++){
set<pair<ull,ull>>se;
scanf("%s",ss+1);
string s;
s+="?#";
for(int i=1;ss[i];i++){
s+=ss[i];
s+="#";
}
s+=".";
vector<int>p(s.size(),0);
HASH<131,998244353>ha1(s);
HASH<1331,1000000007>ha2(s);
for(int i=1,mid=0,r=0;i<s.size();i++){
if(i<r) p[i]=min(r-i+1,p[2*mid-i]);
else p[i]=1;
while(s[i-p[i]]==s[i+p[i]]){
if(s[i+p[i]]=='#'){
se.insert({ha1.get(i-p[i],i+p[i]),ha2.get(i-p[i],i+p[i])});
}
p[i]++;
}
if(i+p[i]-1>=r){
mid=i;
r=i+p[i]-1;
}
}
for(auto &t:se)mp[t]++;
}
int ans=0;
for(auto &[u,v]:mp){
ans+=v==n;
}
printf("%d\n",ans);
}
int main()
{
#ifdef LOCAL
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
time_t beg = clock();
#endif
int t = 1;
//t=read();
while(t--){
solve();
}
return 0;
}
manacher+hash寻找k共同回文串个数(模板)
于 2022-08-23 20:35:33 首次发布