HDU4622 Reincarnation 后缀自动机

Posted 鲸头鹳

tags:

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

http://acm.hdu.edu.cn/showproblem.php?pid=4622

查询一个区间内的不同子串的个数,注意一下注释的地方就可以了。

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 using namespace std;
 8 const int maxn=2010;
 9 char ch[maxn];
10 int siz=0;
11 struct sam{
12     int f,len;
13     int sig[26];
14 }t[maxn*2];int tot,la;
15 int loc[maxn*2]={};
16 int ans[maxn][maxn]={};
17 void add(int z){
18     int i=la;int x=++tot;
19     t[x].len=t[i].len+1;
20     for(;i&&!t[i].sig[z];i=t[i].f)
21         t[i].sig[z]=x;
22     if(!i)t[x].f=1;
23     else{
24         int p=t[i].sig[z];
25         if(t[p].len==t[i].len+1)t[x].f=p;
26         else{
27             int y=++tot;
28             t[y]=t[p];
29             loc[y]=loc[p];//注意loc的转移
30             t[y].len=t[i].len+1;
31             t[x].f=t[p].f=y;
32             for(;i&&t[i].sig[z]==p;i=t[i].f)
33                 t[i].sig[z]=y;
34         }
35     }la=x;
36 }
37 int main(){
38     int T;
39     scanf("%d",&T);
40     while(T-->0){
41         memset(ans,0,sizeof(ans));
42         scanf("%s",ch+1);siz=strlen(ch+1);
43         for(int i=1;i<=siz;i++){
44             memset(t,0,sizeof(t));tot=la=1;
45             memset(loc,0,sizeof(loc));
46             for(int j=i;j<=siz;j++){
47                 loc[tot+1]=j;
48                 add(ch[j]-a);
49             }
50             for(int j=2;j<=tot;j++){
51                 ans[i][loc[j]]+=t[j].len-t[t[j].f].len;
52             }
53             for(int j=i+1;j<=siz;j++){
54                 ans[i][j]+=ans[i][j-1];
55             }
56         }
57         int n,l,r;
58         scanf("%d",&n);
59         for(int i=1;i<=n;i++){scanf("%d%d",&l,&r);printf("%d\n",ans[l][r]);}
60     }
61     return 0;
62 }
View Code

 

以上是关于HDU4622 Reincarnation 后缀自动机的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4622 Reincarnation 后缀自动机

HDU4622 Reincarnation 后缀自动机

HDU 4622 Reincarnation(后缀自动机)

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

HDU 4622 Reincarnation (区间不相同子串个数:字符串哈希 | 后缀数组 | 后缀自动机)

HDU 4622 Reincarnation(SAM)