【SSL】20210817A

【SSL】20210817A


题目描述

给出长度为n的字符串S,以及Q个询问
每个询问给出一个字符串T,判断T是否为S的一个子序列
所有串仅包含小写字母
30%:n<=1e4,q<=1e5
100%:
在这里插入图片描述

输入格式

第一行给出正整数n,Q
第二行给出S
接下来Q行,每行给出一个询问T

输出格式

对于每个询问输出一行表示答案,符合输出YES,不符输出NO

输入样例

3 1
abc
ac

输出样例

YES

解题思路

输入时用f[i,j]表示位置i以后字符j第一次出现的位置
然后预处理所有的f[i,j],然后暴力每次询问。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mx=100100;
int n,q,tong[30][mx],lt[30],f[mx][30],lent;
string s,at;
int main()
{
	scanf("%d%d",&n,&q);
	cin>>s;
	for(int i=0;i<n;++i)
	{
		tong[s[i]-96][++lt[s[i]-96]]=i;
	}
	for(int i=1;i<=26;++i)
	{
		int k=1;
		for(int j=0;j<n;++j)
		{
			if(tong[i][k]<j) k++;
			if(k>lt[i]) f[j][i]=-1;
			else f[j][i]=tong[i][k];
		}
	}
	for(int i=1;i<=q;++i)
	{
		cin>>at;
		lent=at.size();
		int k=0;
		bool flag=true;
		for(int j=0;j<lent;++j)
		{
			if(k<n&&f[k][at[j]-96]>=0)k=f[k][at[j]-96]+1;
			else
			{
				flag=false;
				break;
			}
		}
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
}

谢谢阅读

posted @ 2021-08-18 21:56  基德不基  阅读(55)  评论(0)    收藏  举报