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");
    }
}
posted @ 2012-08-07 17:07  Burn_E  阅读(243)  评论(0)    收藏  举报