NC25138 子串查询

新名词\(get\):序列自动机

思路挺好想的,一共\(n\)个位置,对每个位置建立\(26\)个指针,指向后面第一次出现对应字母的位置。倒序处理一遍即可。

注意:

  • 不存在对应字母的话位置记为\(0\)
  • 下标\(0\)也要初始化

子序列进行匹配时从下标\(0\)开始匹配,下标\(0\)存放的指针代表\(1~n\)中第一次出现对应字母的位置

const int N=1e5+10;
char s[N],t[N];
int ne[N][26];
int n,q;

void init()
{
    for(int i=n-1;i>=0;i--)
    {
        for(int j=0;j<26;j++)
            ne[i][j]=ne[i+1][j];
        ne[i][s[i+1]-'a']=i+1;
    }
}

int main()
{
    cin>>n>>q;

    cin>>s+1;

    init();

    while(q--)
    {
        cin>>t+1;

        int m=strlen(t+1);
        bool ok=true;
        for(int i=1,k=0;i<=m;i++)
        {
            if(ne[k][t[i]-'a'])
                k=ne[k][t[i]-'a'];
            else
            {
                ok=false;
                break;
            }
        }
        if(ok) puts("YES");
        else puts("NO");
    }
    //system("pause");
}
posted @ 2020-12-15 17:32  Dazzling!  阅读(150)  评论(0编辑  收藏  举报