2016-2017 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2016) C Castle (kmp)
题目链接:2016-2017 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2016) C Castle
题意:
初始长为 N 的串 S,以及一个空集合 T。下列有 E 个操作:
1 c
:在 S 串尾添加字符 c
2
:将当前串 S 加入到集合 T 中
3
:要求判断 T 中多少个串是当前串 S 的后缀。
题解:
题意可以转换为有多少个标记的前缀是当前字符串的后缀。
那么我们可以想到kmp的next数组,next数组记录的值就是当前字符串后缀与前缀的最大匹配。
那么通过这个信息就可以推出有多少个标记的前缀是当前字符串的后缀。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 using namespace std; 4 5 const int N=1200007; 6 7 char a[N]; 8 int n,m,nxt[N],cnt[N],i,j,op,ed; 9 char o[2]; 10 11 int main(){ 12 scanf("%d%d%s",&n,&m,a); 13 for (nxt[0] = j = -1, i = 1; i < n; nxt[i++] = j) { 14 while (~j&&a[j + 1] != a[i])j = nxt[j]; 15 if (a[j + 1] == a[i])j++; 16 } 17 F(ii,1,m) 18 { 19 scanf("%d",&op); 20 if(op==1) 21 { 22 scanf("%s",o); 23 a[n++]=*o; 24 while (~j&&a[j + 1] != a[i])j = nxt[j]; 25 if (a[j + 1] == a[i])j++; 26 nxt[i]=j,cnt[i]=cnt[j],i++; 27 }else if(op==2)cnt[n-1]+=ed!=n,ed=n; 28 else printf("%d\n",cnt[n-1]); 29 } 30 return 0; 31 }