wannafly 挑战赛9 B 数一数(kmp)
链接:https://www.nowcoder.com/acm/contest/71/B
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
64bit IO Format: %lld
题目描述
设s,t为两个字符串,定义f(s,t) = t的子串中,与s相等的串的个数。如f("ac","acacac")=3, f("bab","babab")=2。现在给出n个字符串,第i个字符串为si。你需要对,求出,由于答案很大,你只需要输出对 998244353取模后的结果。
输入描述:
第一行一个整数n。i
接下来n行每行一个仅由英文字母构成的非空字符串,第i个字符串代表s
。
输出描述:
共n行,第i行输出
对 998244353取模的结果。
示例1
输入
1 BALDRSKYKirishimaRain
输出
1
备注:
1 ≤ n ≤ 1e6,所有字符串的总长度不超过2e6
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1 #include <bits/stdc++.h> 2 #define mst(a,b) memset((a),(b), sizeof a) 3 #define lowbit(a) ((a)&(-a)) 4 #define IOS ios::sync_with_stdio(0);cin.tie(0); 5 using namespace std; 6 typedef long long ll; 7 typedef unsigned long long ull; 8 typedef pair<int,int> pii; 9 const int mod=998244353; 10 const int maxn=1e6+10; 11 string str[maxn]; 12 int d[maxn]; 13 bool cmp(const int&a,const int&b){ 14 return str[a].length()<str[b].length(); 15 } 16 char x[maxn<<1];int nx[maxn<<1],len; 17 char y[maxn<<1]; 18 int ans[maxn]; 19 bool zero; 20 ll nn=1; 21 void kmp(int pos){ 22 if(zero)return; 23 int sz=str[pos].size(); 24 if(sz<len){nn=0;zero=true;return;} 25 for(int i=0;i<sz;++i)y[i]=str[pos][i]; 26 int i,j; 27 int ans=0; 28 i=j=0; 29 while(i<sz){ 30 while(-1!=j&&y[i]!=x[j])j=nx[j]; 31 ++i;++j; 32 if(j>=len){ 33 ++ans; 34 j=nx[j]; 35 } 36 } 37 nn=nn*ans%mod; 38 } 39 void init(int pos){ 40 len=str[pos].length(); 41 for(int i=0;i<len;++i)x[i]=str[pos][i]; 42 int i,j; 43 j=nx[0]=-1; 44 i=0; 45 while(i<len){ 46 while(-1!=j&&x[i]!=x[j])j=nx[j]; 47 if(x[++i]==x[++j])nx[i]=nx[j]; 48 else nx[i]=j; 49 } 50 } 51 int main() { 52 #ifdef local 53 freopen("inpp","r",stdin); 54 // freopen("outpp","w",stdout); 55 #endif 56 int n;scanf("%d",&n); 57 for(int i=1;i<=n;++i)cin>>str[i],d[i]=i; 58 sort(d+1,d+1+n,cmp); 59 init(d[1]); 60 for(int i=2;i<=n;++i)kmp(d[i]); 61 ans[d[1]]=nn; 62 for(int i=2;i<=n;++i){ 63 if(str[d[i]].length()==len)ans[d[i]]=nn; 64 else ans[d[i]]=0; 65 } 66 for(int i=1;i<=n;++i)printf("%d\n",ans[i]); 67 return 0; 68 }