• bzoj 2780: [Spoj]8093 Sevenk Love Oimaster(广义SAM)


    题目大意:给出n个原串,再给出m个查询串。求每个查询串出现在了多少原串中。

    题解

      直接对原串建一个广义SAM,然后把每一个原串放到SAM上跑一跑,记录一下每一个状态属于多少个原串,用$size$表示。这样的话查询串直接在SAM上跑,如果失配输出0,否则直接输出记录在上面的$size$就好了。

     1 //minamoto
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 char sr[1<<21],z[20];int C=-1,Z;
    19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    20 inline void print(int x){
    21     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    22     while(z[++Z]=x%10+48,x/=10);
    23     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    24 }
    25 const int N=100005;
    26 int fa[N<<1],ch[N<<1][26],sz[N<<1],l[N<<1],las[N<<1],len[N],s[N];
    27 int n,m,cnt=1,last=1,tot=0;
    28 void ins(int c){
    29     int p=last,np=++cnt;last=np,l[np]=l[p]+1;
    30     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    31     if(!p) fa[np]=1;
    32     else{
    33         int q=ch[p][c];
    34         if(l[p]+1==l[q]) fa[np]=q;
    35         else{
    36             int nq=++cnt;l[nq]=l[p]+1;
    37             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    38             fa[nq]=fa[q];fa[q]=fa[np]=nq;
    39             for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    40         }
    41     }
    42 }
    43 inline void update(int x,int y){
    44     for(;x&&las[x]!=y;x=fa[x])
    45     ++sz[x],las[x]=y;
    46 }
    47 int main(){
    48     n=read(),m=read();
    49     for(int i=1;i<=n;++i){
    50         last=1;
    51         char ch;
    52         while((ch=getc())!='
    ') ins(s[++tot]=ch-'a'),++len[i];
    53     }
    54     tot=0;
    55     for(int i=1;i<=n;++i)
    56     for(int j=1,x=1;j<=len[i];++j)
    57     update(x=ch[x][s[++tot]],i);
    58     while(m--){
    59         tot=0;
    60         char c;bool flag=true;int x=1;
    61         while((c=getc())!='
    '&&c!=EOF){
    62             int k=c-'a';
    63             if(flag)
    64             ch[x][k]?x=ch[x][k]:flag=false;
    65         }
    66         print(flag?sz[x]:0);
    67     }
    68     Ot();
    69     return 0;
    70 }
  • 相关阅读:
    RFID之linux下利用PN532对M1卡(饭卡,
    Ubuntu server配置远程VNC服务
    如何在Linux命令行中剪裁图像
    CentOS 6.3 yum安装LAMP(Apache+MySQL+PHP)
    ubuntu16.04 安装Opencv 3.1.0 import cv2 报错ImportError: No module named hdf5
    ubuntu16.04 安装Opencv 3.1.0 fatal error: hdf5.h: 没有那个文件或目录
    通过子网掩码确定主机地址
    单调数据结构
    利用Python分析羊车门问题
    Welcome To My Blog!!!
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9470702.html
Copyright © 2020-2023  润新知