0%

【LGR-225-Div.1.5】洛谷蓝桥杯模拟赛 H P12597 穿睡衣军训

思路讲解

子序列自动机,最重要的是next数组,可以找到从i位置开始,字符下一次出现在哪个位置(下标)(包括i位置)

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
struct seqAuto{	// 子序列自动机 subsequence automaton 
// 可以处理大小写字母,数字,但是可能要改一下base以及next
vector<vector<int>> next;
// 从i位置开始,字符下一次出现在哪个位置(下标)(包括i位置)
char base='a';
seqAuto(const string &s){
next.assign(SZ(s)+5,vector<int>(28,-1));
ROF(i,SZ(s)-1,0){
FOR(j,0,26){
next[i][j]=next[i+1][j];
}
next[i][s[i]-base]=i;
}
}
inline bool isFind(const string &s){ // 传入substr时,必须为const属性
ll idx=0;
FOR(i,0,SZ(s)-1){
if(next[idx][s[i]-base]!=-1){
idx=next[idx][s[i]-base]+1;
}else{
return false;
}
}
return true;
}
};

然后用双指针方式枚举子串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FOR(i,0,SZ(S)-1){	// 双指针
FOR(j,bp,SZ(S)){
assert(j>=i);
ll len=j-i;
if(!sat.isFind(S.substr(i,len))){ // pos,len
bp=j;
if(ans.empty() || len-1>SZ(ans.back())){
ans.clear();
ans.pb(S.substr(i,len-1));
}else if(len-1==SZ(ans.back()) ){
ans.pb(S.substr(i,len-1));
}
break;
}
}
}

AC代码

https://www.luogu.com.cn/record/218545124

心路历程(WA,TLE,MLE……)