HDU 4622 Reincarnation(SAM)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4622 Reincarnation(SAM)相关的知识,希望对你有一定的参考价值。

 

Problem Description
Now you are back,and have a task to do:
Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s.
And you have some query,each time you should calculate f(s[l...r]), s[l...r] means the sub-string of s start from l end at r.
 

 

Input
The first line contains integer T(1<=T<=5), denote the number of the test cases.
For each test cases,the first line contains a string s(1 <= length of s <= 2000).
Denote the length of s by n.
The second line contains an integer Q(1 <= Q <= 10000),denote the number of queries.
Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n), denote a query.
 

 

Output
For each test cases,for each query,print the answer in one line.
 

 

Sample Input
2 bbaba 5 3 4 2 2 2 5 2 4 1 4 baaba 5 3 3 3 4 1 4 3 5 5 5
 

 

Sample Output
3 1 7 5 8 1 3 8 5 1
Hint
I won‘t do anything against hash because I am nice.Of course this problem has a solution that don‘t rely on hash.
 

 

Author
WJMZBMR
 

 

Source
 

ps:代码自带大常数=-=

 

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int N = 2*1e4+10;
 8 
 9 struct QN {
10     int l,r,num;
11     bool operator < (const QN& rhs) const {
12         return l<rhs.l || (l==rhs.l&&r<rhs.r);
13     }
14 }que[N];
15 char s[N];
16 int n,sz,last;
17 int fa[N],ch[N][26],l[N],ans[N];
18 
19 void clear() {
20     sz=0; last=++sz;
21     memset(ch,0,sizeof(ch));
22     memset(l,0,sizeof(l));
23 }
24 void add(int x) {
25     int c=s[x]-a;
26     int p=last,np=++sz; last=np;
27     l[np]=l[p]+1;
28     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
29     if(!p) fa[np]=1;
30     else {
31         int q=ch[p][c];
32         if(l[p]+1==l[q]) fa[np]=q;
33         else {
34             int nq=++sz; l[nq]=l[p]+1;
35             memcpy(ch[nq],ch[q],sizeof(ch[q]));
36             fa[nq]=fa[q];
37             fa[np]=fa[q]=nq;
38             for(;q==ch[p][c];p=fa[p]) ch[p][c]=nq;
39         }
40     }
41 }
42 int read() {
43     char c=getchar(); int x=0;
44     while(!isdigit(c)) c=getchar();
45     while(isdigit(c)) x=x*10+c-0,c=getchar();
46     return x;
47 }
48 int main() {
49     int T,i,j; T=read();
50     while(T--) {
51         scanf("%s",s); n=read();
52         for(i=1;i<=n;i++) {
53             que[i].l=read(),que[i].r=read();
54             que[i].num=i;
55         }
56         sort(que+1,que+n+1);
57         memset(ans,0,sizeof(ans));
58         j=que[1].l;
59         for(i=1;i<=n;i++) {
60             if(i==1&&que[i].l==que[i-1].l)
61                 for(j;j<=que[i].r;j++) add(j-1);
62             else {
63                 clear();
64                 for(j=que[i].l;j<=que[i].r;j++) add(j-1);
65             }
66             for(j=1;j<=sz;j++)
67                 ans[que[i].num]+=l[j]-l[fa[j]];
68         }
69         for(int i=1;i<=n;i++)
70             printf("%d\n",ans[i]);
71     }
72     return 0;
73 }
View Code

 

以上是关于HDU 4622 Reincarnation(SAM)的主要内容,如果未能解决你的问题,请参考以下文章

HDU4622Reincarnation

HDU4622Reincarnation(后缀自动机)

hdu4622-Reincarnation(后缀自动机)

HDU 4622 Reincarnation 后缀自动机

HDU4622: Reincarnation

HDU4622 Reincarnation 后缀自动机