wannafly 挑战赛9 B 数一数(kmp)

链接:https://www.nowcoder.com/acm/contest/71/B

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

设s,t为两个字符串,定义f(s,t) = t的子串中,与s相等的串的个数。如f("ac","acacac")=3, f("bab","babab")=2。现在给出n个字符串,第i个字符串为s i。你需要对 ,求出 ,由于答案很大,你只需要输出对 998244353取模后的结果。

输入描述:

第一行一个整数n。
接下来n行每行一个仅由英文字母构成的非空字符串,第i个字符串代表s
i

输出描述:

共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 }

 

转载于:https://www.cnblogs.com/bibibi/p/8525406.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值