HDU 4622 (后缀自动机)

模板题。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 #define V 3008
 7 
 8 struct sam{
 9     int nt[V*2][26],f[V*2],a[V*2];
10     int last,sum,tot;
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=0; sum=0; tot=0;
18     }
19     void insert(int ch){
20         p=last; last=np=++sum; a[np]=a[p]+1;
21         for (;~p && !~nt[p][ch];p=f[p]) nt[p][ch]=np;
22         if (p==-1) f[np]=0;
23         else
24         {
25             q=nt[p][ch];
26             if (a[q]==a[p]+1) f[np]=q;
27             else
28             {
29                 nq=++sum; a[nq]=a[p]+1;
30                 memcpy(nt[nq],nt[q],sizeof(nt[q]));
31                 f[nq]=f[q];
32                 f[q]=f[np]=nq;
33                 for (;~p && nt[p][ch]==q;p=f[p]) nt[p][ch]=nq;
34             }
35         }
36     }
37     int calc(){
38         return tot+=a[last]-a[f[last]];
39     }
40 
41 }sam;
42 
43 int ans[V][V];
44 
45 void work(){
46     char s[V];
47     scanf("%s",s+1);
48     int n=strlen(s)-1;
49     for (int i=1;i<=n;i++){
50         sam.clear();
51         for (int j=i;j<=n;j++){
52             sam.insert(s[j]-'a');
53             ans[i][j]=sam.calc();
54         }
55     }
56     int Q;
57     scanf("%d",&Q);
58     while (Q--){
59         int x,y;
60         scanf("%d %d",&x,&y);
61         printf("%d\n",ans[x][y]);
62     }
63 }
64 
65 int main(){
66     int T;
67     scanf("%d",&T);
68     while (T--) work();
69 
70     return 0;
71 }

 

posted @ 2016-07-25 17:59  rpSebastian  阅读(201)  评论(0)    收藏  举报