思路
m次询问看字符串是不是给定字符串的子序列
暴力的做法就是直接两个循环去匹配 复杂度m * strlen(a) * Σ(strlen(b)) 这复杂度显然是不可接受的
那么考虑一下预处理
cnt[i][j] 表示当前位置为i下一个字符为j的位置 倒着遍历字符串即可
预处理一遍之后,每次循环跑的次数就只有strlen(b)
题中给定Σ(strlen(b)) 不大于1e6
而预处理的复杂度为 strlen(a) * 26

所以总共在3e7左右 这是允许的 然后既可以ac了
注意一下下标应该从1开始 或者你从0开始 但是表头位置是一个大于strlen(a)的位置也可以
就是说表头位置不能与字符串a的任一位置重叠(废话)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
char s[maxn],a[maxn];
int cnt[maxn][30];
int main(){
    ios::sync_with_stdio(0);
    memset(cnt,-1,sizeof cnt);///初始化都为-1
    cin>>s+1;
    int len=strlen(s+1);
    for(int i=len-1;i>=0;i--){///倒序遍历给定的字符串
        for(int j='a';j<='z';j++){
            cnt[i][j-'a']=cnt[i+1][j-'a'];///把下一个位置的赋值给当前
        }
        cnt[i][s[i+1]-'a']=i+1;///下一个位置的字符覆盖掉
    }
    int m;cin>>m;
    while(m--){
        cin>>a+1;
        int len=strlen(a+1),flag=0,now=0;
        for(int i=1;i<=len;i++){
            if(cnt[now][a[i]-'a']!=-1){///说明存在下一个字符的位置
                now=cnt[now][a[i]-'a'];///位置移动的下一个字符的位置
            }
            else {///不存在下一个字符
                flag=1;
                break;
            }
        }
        if(flag) cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }
    return 0;
}