南昌邀请赛网络赛M题 Subsequence
题意:
给你一个字符串S,长度小于1e5,
然后n次询问,n小于1e5,
每次输入一个字符串T,问T是不是S的子序列。 T长度小于1000
input:
abcdefg 3 abc adg cba
output:
YES
YES
NO
思路:
序列自动机其实就是先预处理出来一个数组,Next[i][j]表示在位置i的后面第一个字符j所在的位置,预处理出Next数组的复杂度就是log(N∗26)
每次询问就是log(M)的复杂度(M是每次询问字符串的长度)。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; char s[maxn]; char t[maxn]; int Next[maxn][27]; void init(int n){ for(int i=n-1;i>=0;--i){ for(int j=0;j<26;++j) Next[i][j]=Next[i+1][j]; Next[i][s[i+1]-'a']=i+1; } } int main(){ scanf("%s",s+1); int n=strlen(s+1); init(n); int q; scanf("%d",&q); while(q--){ scanf("%s",t); int l=strlen(t); int f=1; int now=0; for(int i=0;i<l;++i){ now=Next[now][t[i]-'a']; if(now==0){ f=0; break; } } printf("%s ",(f?"YES":"NO")); } return 0; }