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]='\n';
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())!='\n') 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())!='\n'&&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 }

 

posted @ 2018-08-13 20:24  bztMinamoto  阅读(243)  评论(0编辑  收藏  举报
Live2D