HDU4622 Reincarnation 后缀自动机
http://acm.hdu.edu.cn/showproblem.php?pid=4622
查询一个区间内的不同子串的个数,注意一下注释的地方就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
翻以前的代码发现完全就是魔咒那道题的知识点。。。所以这里改了个更简洁的代码(妈耶我怕不是个智障哦)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ans[maxn][maxn]={},ans1=0; 16 int calc(int x){return t[x].len-t[t[x].f].len;} 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;ans1+=calc(x);} 23 else{ 24 int p=t[i].sig[z]; 25 if(t[p].len==t[i].len+1){t[x].f=p;ans1+=calc(x);} 26 else{ 27 int y=++tot; 28 t[y]=t[p]; 29 t[y].len=t[i].len+1; 30 ans1+=calc(y)-calc(p); 31 t[x].f=t[p].f=y; 32 ans1+=calc(p)+calc(x); 33 for(;i&&t[i].sig[z]==p;i=t[i].f) 34 t[i].sig[z]=y; 35 } 36 } 37 la=x; 38 } 39 int main(){ 40 int T; 41 scanf("%d",&T); 42 while(T-->0){ 43 memset(ans,0,sizeof(ans)); 44 scanf("%s",ch+1);siz=strlen(ch+1); 45 for(int i=1;i<=siz;i++){ 46 memset(t,0,sizeof(t));tot=la=1; 47 ans1=0; 48 for(int j=i;j<=siz;j++){ 49 add(ch[j]-'a'); 50 ans[i][j]=ans1; 51 } 52 } 53 int n,l,r; 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++){scanf("%d%d",&l,&r);printf("%d\n",ans[l][r]);} 56 } 57 return 0; 58 }