zoukankan      html  css  js  c++  java
  • ZOJ3228 Searching the String [AC自动机]

      还是统计串问题,只是分成了同一种串允许互相覆盖和不允许互相覆盖两种情况。

      对于允许互相覆盖的情况,就是模版了。对于不允许覆盖的情况,只要记录下该串最后一次出现并且被统计的位置即可,能统计的条件是lasp[id]+len[id]<=pos。

    #include <string.h>
    #include <stdio.h>
    #define MAXL 600001
    #define MAXN 100001
    #define INF 0x3fffffff
    char s[MAXN],s1[10];
    int n,type,stp[MAXN],sps[MAXN];
    int next[MAXL][26],fail[MAXL],flag[MAXL],lent[MAXL],lasp[MAXL],ans[MAXL][2],pos;
    int newnode(){
        for(int i=0;i<26;i++)next[pos][i]=0;
        flag[pos]=fail[pos]=0;
        return pos++;
    }
    void insert(char *s,int type,int sid){
        int p=0,len=0;
        for(int i=0;s[i];i++,len++){
            int k=s[i]-'a',&x=next[p][k];
            p=x?x:x=newnode();
        }
        //初始化单词末尾节点的一些信息
        ans[p]={0,0};
        lasp[p]=-INF;
        lent[p]=len;
        //1代表查询0,2代表查询1,3代表两种查询
        flag[p]|=(1<<type);
        //记录查询的种类和对应的位置
        stp[sid]=type;
        sps[sid]=p;
    }
    int q[MAXL],front,rear;
    void makenext(){
        q[front=rear=0]=0,rear++;
        while(front<rear){
            int u=q[front++];
            for(int i=0;i<26;i++){
                int v=next[u][i];
                if(v==0)next[u][i]=next[fail[u]][i];
                else q[rear++]=v;
                if(v&&u)fail[v]=next[fail[u]][i];
            }
        }
    }
    void makeans(char *s){
        for(int i=0,p=0;s[i];i++){
            int k=s[i]-'a';
            p=next[p][k];
            for(int f=p;f;f=fail[f]){
                //对于可重叠覆盖的情况,直接统计
                if(flag[f]&1){
                    ans[f][0]++;
                }
                //对于不可重叠覆盖的情况,选取后记录最后选取的位置
                if(flag[f]&2){
                    if(lasp[f]+lent[f]<=i){
                        ans[f][1]++;
                        lasp[f]=i;
                    }
                }
            }
        }
    }
    int main(){
        //freopen("test.in","r",stdin);
        int cas=1;
        while(scanf("%s",s)!=EOF){
            scanf("%d",&n);
            pos=0;newnode();
            for(int i=1;i<=n;i++){
                scanf("%d%s",&type,s1);
                insert(s1,type,i);
            }
            makenext();
            makeans(s);
            printf("Case %d\n",cas++);
            for(int i=1;i<=n;i++){
                printf("%d\n",ans[sps[i]][stp[i]]);
            }
            printf("\n");
        }
    }
  • 相关阅读:
    对称加密与非对称加密
    mysql 数据库备份
    Linux安装VM虚拟机
    Ubuntu安装桌面
    POM 总是提示找不到依赖
    Wine解决界面乱码
    There was an unexpected error (type=Not Found, status=404). /WEB-INF/views/login.jsp
    Linux打开chm文件
    vim 查找模式
    spring总结(02)注解
  • 原文地址:https://www.cnblogs.com/swm8023/p/2627020.html
Copyright © 2011-2022 走看看