题解:CF223B Two Strings

· · 题解

水。

f(i) 表示 s 的前 i 个字符中,存在等于 t_{[1,f(i)]} 的最长子序列。

然后枚举 $s$ 中的位置 $1 \le i \le |s|$,这个字符放在 $t$ 中的某一个位置 $j$,如果满足 $f(i-1) \ge j-1,g(i+1) \ge |t| - j$,那么这个位置就是符合条件的,否则就不符合。 但是直接枚举 $j$ 是平方的,因为考虑 $f(i-1)$ 和 $g(i+1)$ 的取值并放在 $t$ 上考虑。即考虑 $t$ 上的区间 $[|t|-g(i-1),f(i-1)+1]$。若区间合法并且该区间内有等于 $s_i$ 的字符则符合条件,否则不符合。 至于怎么找区间内有没有对应的字符,前缀和即可。 ```cpp #include <bits/stdc++.h> using namespace std; const int N=2e5+5; char s[N],t[N]; int f[N],g[N]; int sum[N][28]; int main(){ scanf("%s",s+1); scanf("%s",t+1); int n=strlen(s+1),m=strlen(t+1); int j=1; f[1]=0; for(int i=1;i<=n;++i){ f[i]=f[i-1]; if(s[i]==t[j] && j<=m) f[i]++,j++; } g[n+1]=0; j=m; for(int i=n;i>=1;i--){ g[i]=g[i+1]; if(s[i]==t[j] && j>=1) g[i]++,j--; } for(int i=1;i<=m;++i) sum[i][t[i]-'a']++; for(int j=0;j<26;++j) for(int i=1;i<=m+1;++i) sum[i][j]+=sum[i-1][j]; for(int i=1;i<=n;++i){ int l=m-g[i+1],r=f[i-1]+1; if(l>r || sum[r][s[i]-'a']-sum[max(l-1,0)][s[i]-'a']==0){ printf("No"); return 0; } } printf("Yes\n"); } ```