题目:CF1203D2 Remove the Substring (hard version)
昨天初赛才考的。。今早就做到了原题!!我可能缺欧皇,总是碰到考完就做到原题或者考前看过原题的情况。。
就设s2[1~pre[i]]为s1[1~i]的子序列,s2[suf[i]~m]为s1[i~n]的子序列。然后每次指针移动计算一下预处理。接着扫描一遍就行。
1 #include<stdio.h>
2 #include<string.h>
3 #define it register int
4 #define il inline
5 const int N=1000005;
6 char s1[N],s2[N];
7 int n,m,ans,pre[N],suf[N];
8 il int Max(it p,it q){
9 return p>q?p:q;
10 }
11 int main(){
12 scanf("%s%s",s1+1,s2+1);
13 n=strlen(s1+1),m=strlen(s2+1);
14 for(it i=1,j=1;i<=n;++i){
15 pre[i]=pre[i-1];
16 if(s1[i]==s2[j]) ++j,++pre[i];
17 }
18 suf[n+1]=m+1;
19 for(it i=n,j=m;i;--i){
20 suf[i]=suf[i+1];
21 if(s1[i]==s2[j]) --j,--suf[i];
22 }
23 /*
24 1~pre[i]是s1的子序列
25 suf[i]~m是s1的子序列
26 */
27 for(it i=0,j=0;i<=n;++i){
28 while(j<=n&&suf[j]<=pre[i]+1) ++j;
29 if(suf[j]<=pre[i]+1) break;
30 ans=Max(j-i-2,ans);
31 }
32 for(it i=1;i<=n;++i) if(pre[i]==m) ans=Max(ans,n-i);
33 printf("%d",ans);
34 return 0;
35 }