涉及知识点:
solution:
- 这是牛客今天的每日一题,大家可以写题解领取牛币(牛币可以兑换卫衣,抱枕!)戳这里进入活动页面
- 题意:给出母串 s,给出 m 次询问,每次询问给出的子串 si 是否是 s 的子序列
- 字符串s的长度为1e6,给出的子串si的长度总和也为1e6,如果n方暴力枚举一定会超时
- 所以我们可以对字符串s做一下处理
- 设nex[ i ][ 'a' - 'z' ] 表示第 i 个位置的字母后第一个 'a' - 'z' 字母的位置,提前预处理母串s,查询子串 si 就可以简化到O( n )
- 这样我们遍历子串si,实际上就相当于在母串s上不断地跳跃(不懂的可以结合代码模拟一下),如果遍历完子串si,说明si 是 s 的子序列,否则不是
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e6 + 5;
char s[maxn];
int nex[maxn][26];
int main()
{
scanf("%s",s+1);
int l = strlen(s+1);
for(int i=l-1;i>=0;i--)
{
for(int j=0;j<26;j++)
{
nex[i][j] = nex[i+1][j];
}
nex[i][s[i+1]-'a'] = i+1;
}
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s+1);
l = strlen(s+1);
int k = 0,flag = 0;
for(int i=1;i<=l;i++)
{
if(nex[k][s[i]-'a'])
k = nex[k][s[i]-'a'];
else{
flag = 1;
break ;
}
}
if(flag)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}