首页 > 其他 > 详细

Nowcoder contest 392 J (模板题)【序列自动机】

时间:2019-03-10 10:49:25      阅读:129      评论:0      收藏:0      [点我收藏+]

<题目链接>

题目大意:
给你一个母串A,然后进行q次询问,每次询问给定一个长度不超过母串的字符串,问你这个字符串是否是母串的子串。

解题分析:
序列自动机模板题。本题的思想就是考虑贪心的去匹配,我们希望当前匹配到的位置越靠前越好。所以对于母串每一位都记一下下一次出现某个字符的位置。匹配的时候从第零位(虚根)开始,如果能一直匹配下去就是$Yes$ ,否则就是 $No$,这些操作就是用序列自动机简单实现。

单次查询的复杂度是$O(|B_i|)$ 的,序列自动机预处理的复杂度是 $O(26|A|)$的。总时间复杂度是$O(26|A|+\sum_{i=1}^N |B_i|)$。

序列自动机

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6+5;
int n,m,T;
char str[N],s[N];
int nxt[N][26],pos[26];
 
void init(){     //预处理主串的信息
    n=strlen(str+1);
    for(int i=0;i<26;i++) pos[i]=n+1;    //a~z中每个字母的下一个字母所对应的位置
    for(int i=n;~i;i--){
        for(int j=0;j<26;j++)
            nxt[i][j]=pos[j]; //记录下下一次出现这个字符的位置
        pos[str[i]-a]=i;    //更新a[i]最对应的字母对应的当前最靠前的位置
    }
}
bool solve(){
    scanf("%s",s+1);
    m=strlen(s+1);int x=0;   //x从0开始,0作为虚根
    for(int i=1;i<=m;i++){
        int v=s[i]-a;
        if(nxt[x][v]==n+1) return false;    //如果下一个出现字符的位置不存在,则说明该子串并未完全匹配
        x=nxt[x][v];
    } return true;
}
 
int main(){
    scanf("%s",str+1);
    cin>>T;init();
    while(T--) solve()?puts("Yes"):puts("No");
}

 

SAM:

#include <bits/stdc++.h>
using namespace std;
 
const int MaxN = 1e6 + 5;
 
int N, L;
char str[MaxN], str2[MaxN];
 
struct SAM {
  int cntv;
  int nxt[MaxN];
  int last[26], ch[26][MaxN];
  SAM() { nxt[0] = -1; }
 
  inline void insert(int c) {
    cntv++; nxt[cntv] = last[c];
    for (int i = 0; i < 26; ++i)
      for (int p = last[i]; p != -1 && ch[c][p] == 0; p = nxt[p])
        ch[c][p] = cntv;
    last[c] = cntv;
  }
 
  inline bool check(int u, int x) {
    if (x == L) return true;
    int c = str2[x] - a;
    if (ch[c][u] == 0) return false;
    return check(ch[c][u], x + 1);
  }
} sam;
 
void init() {
  scanf("%s", str);
  scanf("%d", &N);
  for (int i = 0; str[i]; ++i) sam.insert(str[i] - a);   
}
 
void solve() {
  for (int i = 1; i <= N; ++i) {
    scanf("%s", str2);
    L = strlen(str2);
    puts(sam.check(0, 0) ? "Yes" : "No");
  }
}
 
int main() {
  init();
  solve();
}

 

Nowcoder contest 392 J (模板题)【序列自动机】

原文:https://www.cnblogs.com/00isok/p/10503988.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!