• ZOJ3228 Searching the String(AC自动机)


    题目大概是给一个主串,询问若干个模式串出现次数,其中有些模式串要求不能重叠。

    对于可以重叠的就是一个直白的多模式匹配问题;而不可重叠,在匹配过程中贪心地记录当前匹配的主串位置,然后每当出现一个新匹配根据记录的位置判断这个新匹配是否成立,最后更新位置。

    另外,考虑到数据可以出现多个模式串相同的情况,实现要做一些处理:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 666666
     7 //-1 none, 0 overlap, 1 not, 2 both
     8 int tn,ch[MAXN][26],fail[MAXN],flag[MAXN],len[MAXN];
     9 int insert(char *s,int k){
    10     int x=0,l=0;
    11     for(int i=0; s[i]; ++i){
    12         int y=s[i]-'a';
    13         if(ch[x][y]==0) ch[x][y]=++tn;
    14         x=ch[x][y];
    15         ++l;
    16     }
    17     len[x]=l;
    18     if(flag[x]==-1) flag[x]=k;
    19     else if(flag[x]==0 && k==1) flag[x]=2;
    20     else if(flag[x]==1 && k==0) flag[x]=2;
    21     return x;
    22 }
    23 void getfail(){
    24     memset(fail,0,sizeof(flag));
    25     queue<int> que;
    26     for(int i=0; i<26; ++i){
    27         if(ch[0][i]) que.push(ch[0][i]);
    28     }
    29     while(!que.empty()){
    30         int x=que.front(); que.pop();
    31         for(int i=0; i<26; ++i){
    32             if(ch[x][i]){
    33                 que.push(ch[x][i]);
    34                 fail[ch[x][i]]=ch[fail[x]][i];
    35             }else ch[x][i]=ch[fail[x]][i];
    36         }
    37     }
    38 }
    39 int last[MAXN],ans[2][MAXN],first[111111],second[111111];
    40 char str[111111];
    41 void query(){
    42     int x=0;
    43     for(int i=0; str[i]; ++i){
    44         int y=str[i]-'a';
    45         int tmp=x=ch[x][y];
    46         while(tmp){
    47             if(flag[tmp]!=-1 && flag[tmp]!=1) ++ans[0][tmp];
    48             if(flag[tmp]!=-1 && flag[tmp]!=0){
    49                 if(last[tmp]==-1 || i-last[tmp]>=len[tmp]){
    50                     last[tmp]=i;
    51                     ++ans[1][tmp];
    52                 }
    53             }
    54             tmp=fail[tmp];
    55         }
    56     }
    57 }
    58 int main(){
    59     int n,cse=0;
    60     char s[11];
    61     while(~scanf("%s",str)){
    62         tn=0;
    63         memset(ch,0,sizeof(ch));
    64         memset(flag,-1,sizeof(flag));
    65         scanf("%d",&n);
    66         for(int i=0; i<n; ++i){
    67             scanf("%d%s",&first[i],s);
    68             second[i]=insert(s,first[i]);
    69         }
    70         getfail();
    71         memset(ans,0,sizeof(ans));
    72         memset(last,-1,sizeof(last));
    73         query();
    74         printf("Case %d
    ",++cse);
    75         for(int i=0; i<n; ++i){
    76             printf("%d
    ",ans[first[i]][second[i]]);
    77         }
    78         putchar('
    ');
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    git 配置免密上传,配置ssh key
    spring @value 为什么没有获取到值
    idea 下maven 导入本地jar,以及导入之后 java不能引用问题
    在git远程仓创建项目之后,提交本地项目的使用方法
    mysql 查询数据库参数命令
    spring Existing transaction found for transaction marked with propagation 'never' 解决
    nginx for ubuntu
    spring中for循环中事务
    面向接口编程详解(一)——思想基础
    实战MEF(5):导出元数据
  • 原文地址:https://www.cnblogs.com/WABoss/p/5353733.html
Copyright © 2020-2023  润新知