Solution

直观的想法是直接扫描两个字符串进行比较。这样的复杂度是 的。

然后可以发现子序列中字母的相对位置是不变的,所以可以维护一个数组 表示第 个位置之后最近的字母 所在的位置。这个数组可以 处理: ,然后在倒序循环一遍即可预处理出 数组。

对于每个要判断的字符串 ,建立一个指针 ,初始值为 。然后判断 的每一位是否在 中出现,并更新指针 即可。

时间复杂度: 。字符集常数较大。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e6+10;
int n,m,nxt[maxn][30];
char s[maxn];
int main(){
    ios::sync_with_stdio(false);
    cin>>s+1;
    m=strlen(s+1);
    for(int i=1;i<=m;i++)
        nxt[i-1][s[i]-'a']=i;
    for(int i=m-1;i>=0;i--)
        for(int j=0;j<26;j++)
            if(!nxt[i][j])
                nxt[i][j]=nxt[i+1][j];
    string t;
    int x,y;
    cin>>n;
    while(n--){
        cin>>t;
        m=t.size();
        x=y=0;
        for(int i=0;i<m;i++){
            x=nxt[x][t[i]-'a'];
            if(!x){
                y=1;
                break;
            }
        }
        if(y)
            puts("No");
        else
            puts("Yes");
    }
    return 0;
}