zoukankan      html  css  js  c++  java
  • hdu5853 (后缀自动机)

    Problem Jong Hyok and String

    题目大意

      给你n个字符串,有q个询问。

      定义set(s)={(i,j)} 表示 s在第i个字符串中出现,且末尾位置为j。

      对于一个询问,求set(Qi)=set(t) ,t的数量。

      (n,q<=10^5 , 字符串总长<=10^5)

    解题分析

      直接将n个串塞进一个后缀自动机里面。

      对于一个询问串qi,找到其在后缀自动机中出现的位置j。

      则答案为len[j] - len[fail[j]] 。 (具体为什么还需要好好斟酌一下)

    参考程序

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 #define V 100008
     7 int ans[V];
     8 struct sam{
     9     int nt[V*2][26],f[V*2],a[V*2],rig[V*2];
    10     int last,sum,len;
    11     int p,q,np,nq;
    12 
    13     void clear(){
    14         memset(f,-1,sizeof(f));
    15         memset(a,0,sizeof(a));
    16         memset(nt,-1,sizeof(nt));
    17         last = sum = len=0;
    18     }
    19     void insert(int ch){
    20         len++;
    21         if (~nt[last][ch] && a[nt[last][ch]]==len){
    22             last=nt[last][ch]; return;
    23         }
    24         p=last; last=np=++sum; a[np]=a[p]+1; rig[np]=1;
    25         for (;~p && !~nt[p][ch];p=f[p]) nt[p][ch]=np;
    26         if (p==-1) f[np]=0;
    27         else
    28         {
    29             q=nt[p][ch];
    30             if (a[q]==a[p]+1) f[np]=q;
    31             else
    32             {
    33                 nq=++sum; a[nq]=a[p]+1;
    34                 memcpy(nt[nq],nt[q],sizeof(nt[q]));
    35                 f[nq]=f[q];
    36                 f[q]=f[np]=nq;
    37                 for (;~p && nt[p][ch]==q;p=f[p]) nt[p][ch]=nq;
    38             }
    39         }
    40     }
    41     int work(char *s,int l){
    42         int now=0;
    43         for (int i=1;i<=l;i++){
    44             if (nt[now][s[i]-'a']==-1) return 0;
    45             now=nt[now][s[i]-'a'];  
    46         }
    47         return a[now]-a[f[now]];
    48     }
    49 }sam;
    50 
    51 char str[V];
    52 void work(){
    53     sam.clear();
    54     int n,m;
    55     scanf("%d %d",&n,&m);
    56     for (int i=1;i<=n;i++){
    57         sam.len=sam.last=0;
    58         scanf("%s",str+1);
    59         int len=strlen(str+1);
    60         for (int j=1;j<=len;j++) sam.insert(str[j]-'a');
    61     }
    62     for (int i=1;i<=m;i++){
    63         scanf("%s",str+1);
    64         int len=strlen(str+1);
    65         printf("%d
    ",sam.work(str,len));   
    66     }
    67 }
    68 
    69 int main(){
    70     int T;
    71     scanf("%d",&T);
    72     for (int t=1;t<=T;t++){
    73         printf("Case #%d:
    ",t );
    74         work();
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    很长的下拉框菜单
    Pure CSS Buttons – Good Button Style and No Images
    ssh 配置
    php大量session存储到内存中,散列及过期回收
    array_append_distinct, array_erase函数
    关于C# 中的Attribute 特性(转载)
    Jquery如何操作Table的某一个td
    ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期
    ASP.NET应用程序生命周期趣谈(五) IIS7瞎说
    ASP.NET应用程序生命周期趣谈(三)
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5778193.html
Copyright © 2011-2022 走看看