字符串

题意:

给定一个字符串,求包含ACCEPT但不包含WA且长度大于k的子串数量。

题解:

子序列自动机,一个我较少写的算法(ps:可能是用到了没意识到),mark。。。

子序列自动机的基本概念是用二维数组保存对于i位置 j字符第一次出现的位置为nxt[i][j],通过这种方式来维护字串ACCEPT和子串WA的子序列位置。

这是一个很容易理解,很多人没有给它命名的算法。该题的答案就是对于每个以i结尾的字符串i,计算后一个“WA",“A”与后一个“ACCEPT”中的“A”的上一位合法字符串长度累和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void get_next(){
for(int i=n;i>=0;i--){
for(int j=0;j<26;j++){
if(i==n) nxt[i][j]=n;
else nxt[i][j]=nxt[i+1][j];
}
if(i!=n) nxt[i][s[i]-'A']=i;
}
}

int get_pos(int st,string s){
int first=1;
for(auto ch:s){
if(first) st=nxt[st][ch-'A'];
else st=nxt[st+1][ch-'A'];
first=0;
if(st==n) return st;
}
return st;
}

void slove(){
cin>>n>>k>>s;
get_next();
string ac="ACCEPT",wa="WA";
ll ans=0;
for(int i=0;i<n;i++){
int r1=get_pos(i,ac),r2=get_pos(i,wa);
r1=max(r1,i+k-1);
ans=ans+max(r2-r1,0ll);
}
cout<<ans<<endl;
}