题目还时候不改一样的脑残: 具体意思就是从一个串中找其他的字串,当时我就想KMP ,但是就炸了,很是心寒 ,后来看了一下别人的提交忽然恍然大悟。。。。心中翻腾着一万只哈士奇
设s,t为两个字符串,定义f(s,t) = t的子串中,与s相等的串的个数。如f("ac","acacac")=3, f("bab","babab")=2。现在给出n个字符串,第i个字符串为s
i。你需要对
,求出
,由于答案很大,你只需要输出对 998244353取模后的结果。
输入描述:
第一行一个整数n。 接下来n行每行一个仅由英文字母构成的非空字符串,第i个字符串代表si。
输出描述:
共n行,第i行输出对 998244353取模的结果。
示例1
输入
1 BALDRSKYKirishimaRain
输出
1
备注:
1 ≤ n ≤ 106,所有字符串的总长度不超过2*106
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <queue> using namespace std; const int N=2E6; const int MOD=998244353; int n,p,len,f[N],ans; char s[N]; vector <char> G[N]; int find(int k1,int k2) { int j=0,m=G[k1].size(),n=G[k2].size(),sum=0; for (int i=0;i<n;i++) { while (j&&G[k1][j] != G[k2][i]) j=f[j]; if (G[k1][j]==G[k2][i]) j++; if (j==m) sum++; } return sum; } void getfail(int k) // m=length s { int m=G[k].size(); for (int i=1;i<m;i++) { int j=f[i]; while (j && G[k][i]!=G[k][j]) j=f[j]; f[i+1]=G[k][i]==G[k][j]?j+1:0; } } int main() { cin>>n; p=1; for (int i=1;i<=n;i++) { scanf("%s",s); len=strlen(s); for (int j=0;j<len;j++) G[i].push_back(s[j]); if (len<G[p].size()) p=i; } ans=1; for (int i=1;i<=n;i++) { getfail(p); ans=(long long)ans*find(p,i)%MOD; } for (int i=1;i<=n;i++) if (G[i].size()==G[p].size()) printf("%d\n",ans); else printf("0\n"); }