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 }