• hdu_4787_GRE Words Revenge(在线AC自动机)


    题目链接:hdu_4787_GRE Words Revenge

    题意:

    总共有n个操作,2种操作。每行读入一个字符串。

    1.如果字符串以+开头,此为单词(即模式串,不考虑重复)

    2.如果字符串以?开头,此为文章(即文本串,查询在此之前的单词在文本串中出现的次数)

    题解:

    强制在线的AC自动机

    贴个大牛的详细题解http://blog.csdn.net/no__stop/article/details/16823479

    这样的带合并操作的AC自动机用第二种建树的方式比较方便

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 using namespace std;
     4 
     5 const int AC_N=1e5+7,tyn=2,M=5e6+10;//数量乘串长,类型数
     6 struct AC_automation{
     7     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
     8     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
     9     void init(){tot=-1,fail[0]=-1,nw();}
    10     void insert(char *s,int x=0){
    11         for(int i=0,w;s[i];x=tr[x][w],i++)
    12             if(tr[x][w=s[i]-'0']==-1)nw(),tr[x][w]=tot;
    13         cnt[x]=1;//串尾标记
    14     }
    15     void build(int head=1,int tail=0){
    16         F(i,0,1)if(~tr[0][i])Q[++tail]=tr[0][i],fail[tr[0][i]]=0;
    17         while(head<=tail){
    18             for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){
    19                 for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
    20                     if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
    21                 Q[++tail]=tr[x][i];
    22             }
    23         }
    24     }
    25     int ask(char *s,int ans=0){
    26         for(int w,i=0,x=0,j;s[i];i++){
    27             while(tr[x][w=s[i]-'0']==-1&&x)x=fail[x];
    28             x=tr[x][w],x=(~x)?x:0,j=x;
    29             while(j){if(cnt[j])ans++;j=fail[j];}
    30         }
    31         return ans;
    32     }
    33     
    34 }a,b;
    35 
    36 char s[M],tps[M];
    37 int t,n,an,sqr=2000,bcnt;
    38 
    39 void dfs(int r1,int r2)//将b中以r2为根结点的树合并到a中以r1为根结点的树中
    40 {
    41     F(i,0,1)if(~b.tr[r2][i])
    42     {
    43         if(a.tr[r1][i]==-1)a.nw(),a.tr[r1][i]=a.tot;
    44         a.cnt[a.tr[r1][i]]|=b.cnt[b.tr[r2][i]];
    45         dfs(a.tr[r1][i],b.tr[r2][i]);
    46     }
    47 }
    48 
    49 void join(){dfs(0,0),b.init(),a.build();}//将b合并到a中
    50 
    51 void decrypt()
    52 {
    53     int len=strlen(s);
    54     int k=an%(len-1),ed=0;
    55     F(i,1,len-1)tps[i]=s[i];
    56     F(i,k+1,len-1)s[++ed]=tps[i];
    57     F(i,1,k)s[++ed]=tps[i];
    58 }
    59 
    60 int main()
    61 {
    62     scanf("%d",&t);
    63     F(ic,1,t)
    64     {
    65         printf("Case #%d:
    ",ic);
    66         scanf("%d",&n);
    67         a.init(),b.init(),an=bcnt=0;
    68         F(i,1,n)
    69         {
    70             scanf("%s",s),decrypt();
    71             if(s[0]=='+')
    72             {
    73                 b.insert(s+1),b.build(),bcnt++;
    74                 if(bcnt>sqr)join();
    75             }else printf("%d
    ",(an=a.ask(s+1)+b.ask(s+1)));
    76         }
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    Django同步数据库(/manage.py makemigrations) 报错
    python中global和nonlocal用法的详细说明
    linux系统下载pycharm
    第一次博客作业
    结对编程作业
    团队介绍与选题报告
    FTP的时间为什么比系统时间晚了八个小时?
    新的部落格
    Enter键提交表单
    Android动画RotateAnimation(fromDegrees, toDegrees, pivotX,pivotY)参数
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5832022.html
Copyright © 2020-2023  润新知