解析:
这道题题目读懂其实是很简单的。因为题目求得是乘积,所以只要有一项为0 ,那么答案就为0.
所以对于s,t串来说,如果len(s)>len(t),那么f(s,t)=0,如果len(s)==len(t)&&strcmp(s,t)!=0,那么f(s,t)=0
按照这个规律,那么其实所有答案中,只有长度最短的串可能不为0,其余全部为0.
并且当有多个长度最短的串时,如果这些最短串不全部相等,那么他们的答案全为0。
所以在这么多苛刻的条件下,不为0的情况当且只在所有长度最短串相等时出现
这样我们只要用其中一个长度最短串去用KMP匹配剩余的全部串,然后在输出就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define MOD 998244353
#define INF 0x3f3f3f3f
using namespace std;
typedef long long int lli;
const int MAXNN = 3e6+100;
const int MAXN = 1e6+100;
char str[MAXNN];
int mark[MAXN];
int vis[MAXN];
int nex[MAXNN];
void makeNext(const char P[],int next[])
{
int q,k;
int m = strlen(P);
next[0] = 0;
for (q = 1,k = 0; q < m; ++q)
{
while(k > 0 && P[q] != P[k])
k = next[k-1];
if (P[q] == P[k])
{
k++;
}
next[q] = k;
}
}
lli kmp(const char T[],const char P[],int next[])
{
int n,m;
int i,q;
lli ans=0;
n = strlen(T);
m = strlen(P);
makeNext(P,next);
for (i = 0,q = 0; i < n; ++i)
{
while(q > 0 && P[q] != T[i])
q = next[q-1];
if (P[q] == T[i])
{
q++;
}
if (q == m)
{
ans++;
}
}
return ans%MOD;
}
int main()
{
int n;
scanf("%d",&n);
int lcn=0;
int minn=INF;
int minum=-1;
for(int i=0;i<n;i++)
{
scanf("%s",str+lcn);
mark[i]=lcn;
int len=strlen(str+lcn);
if(minn>len)
{
minn=len;
minum=i;
}
lcn=lcn+len+1;
}
int flag=0;
for(int i=0;i<n;i++)
{
if(strlen(str+mark[i])==minn)
{
if(strcmp(str+mark[minum],str+mark[i]))
{
flag=1;
break;
}
else
{
vis[i]=1;
}
}
}
if(flag)
{
for(int i=0;i<n;i++)
{
printf("0\n");
}
}
else
{
lli res=1;
for(int i=0;i<n;i++)
{
lli tt=kmp(str+mark[i],str+mark[minum],nex);
if(tt==0)
{
flag=1;
break;
}
else
{
res=(res*tt)%MOD;
}
}
if(flag)
{
for(int i=0;i<n;i++)
{
printf("0\n");
}
}
else
{
for(int i=0;i<n;i++)
{
if(vis[i]) printf("%lld\n",res);
else printf("0\n");
}
}
}
return 0;
}