Congshin said: Finished the topic remember Summary, convenient later review.
Spoj SUBST1
Topic Link: Click to open the link
Test instructions: Give a string to find the number of different substrings.
Idea: Suppose all substrings are different, the answer is len* (len+1)/2; However, this is not the case ... Now we'll find the duplicate substring:
First, the suffix is sorted, for the suffix I can generate Len-sa[i] substrings, which have Height[i] substring and the i-1 suffix generated by the substring duplicate;
So the answer is len* (len+1)/2-segema (Height[i]).
CPP Code:
Spoj disubstr#include <cstring> #include <iostream> #include <cstdio> #include <vector>using namespace Std;const int MAXN =1010;int t1[maxn],t2[maxn],c[maxn];bool cmp (int *r, int a,int b, int l) {return r[a]==r[b]&am P;&R[A+1]==R[B+1];} void da (int sa[],int rank[],int str[],int height[],int n,int m) {n++;int i,j,p,*x=t1,*y=t2;for (i=0;i<m;i++) c[i]=0; for (i=0;i<n;i++) c[x[i]=str[i]]++;for (i=1;i<m;i++) c[i]+=c[i-1];for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for ( J=1;j<=n;j<<=1) {p=0;for (i=n-j;i<n;i++) y[p++]=i;for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; for (i=0;i<m;i++) c[i]=0;for (i=0;i<n;i++) c[x[y[i]]]++;for (i=1;i<m;i++) c[i]+=c[i-1];for (i=n-1;i>=0; i--) Sa[--c[x[y[i]]]]=y[i];swap (x, y);p =1;x[sa[0]]=0;for (i=1;i<n;i++) {X[sa[i]]=y[sa[i-1]]==y[sa[i]] && ; Y[SA[I-1]+J]==Y[SA[I]+J]?P-1:P++;//X[SA[I]]=CMP (y,sa[i-1],sa[i],j)? p-1:p++;} if (p>=n) break;m=p;} int k=0;n--;for (i=0;i<=n;i++) rank[sa[i]]=i;for (i=0;i<n;i++) {if (k) k--;j=sa[rank[i]-1];while (Str[i+k]==str[j+k]) k++;height[rank[i]]=k;} Char st[maxn];int rank[maxn],str[maxn],sa[maxn],height[maxn];int Main () {//freopen ("data.in", "R", stdin); int t;scanf ("%d", &t), while (t--) {scanf ("%s", St), Int. l=strlen (ST); for (int i=0;i<=l;i++) {str[i]=st[i];} Da (sa,rank,str,height,l,128); Long long ans= (long Long) (l+1) * (l)/2;for (int i=2;i<=l;i++) {ans-=height[i];} Cout<<ans<<endl;} return 0;}
POJ 2406:
Test instructions: Given a string, a maximum number of loop sections can be found.
Idea: Find the largest k to make LCP (0,k) =k and LCP (0,k)%k==0;
But I wrote it in KMP. Next[n] is the maximum value of LCP (0,len-(next[n)) ==next[n] after the string is reversed .
Cpp:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int MAXN =2000000;int next[maxn];char str[maxn];void get_next (int len) {int i=0,j=-1; Next[i]=j;while (I<len) {if (str[i]==str[j]| | J==-1) {++i,++j; Next[i]=j;} else {j=next[j];}}} int main () {freopen ("data.in", "R", stdin), while (~SCANF ("%s", str)) {//cout<<str<<endl;if (str[0]== '. ') Break;int Len=strlen (str), Get_next (len), if (len% (Len-next[len]) ==0) printf ("%d\n", len/(Len-next[len])); else puts (" 1 ");} return 0;}
Spoj REPEATS
Test instructions: Look for the cycle sequence with the most cycles and the number of output cycles.
Ideas:
Cpp:
#include <cstring> #include <iostream> #include <cstdio> #include <vector>using namespace std; const int MAXN =200010;int t1[maxn],t2[maxn],c[maxn];int str[maxn],sa[maxn],rank[maxn],height[maxn];bool cmp (int *r, int a,int b, int l) {return r[a]==r[b]&&r[a+1]==r[b+1];} void da (int n,int m) {n++;int i,j,p,*x=t1,*y=t2;for (i=0;i<m;i++) c[i]=0;for (i=0;i<n;i++) c[x[i]=str[i]]++;for (i =1;i<m;i++) c[i]+=c[i-1];for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for (j=1;j<=n;j<<=1) {p=0;for (i=n-j;i <n;i++) y[p++]=i;for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;for (i=0;i<m;i++) c[i]=0;for (i=0;i<n;i + +) c[x[y[i]]]++;for (i=1;i<m;i++) c[i]+=c[i-1];for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];swap (x, y);p =1;x[sa [0]] =0;for (i=1;i<n;i++) {x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;//x[sa[i]]=cmp ( y,sa[i-1],sa[i],j)? p-1:p++;} if (p>=n) break;m=p;} int k=0;n--;for (i=0;i<=n;i++) rank[sa[i]]=i;for (i=0;i<n;i++) {if (k) K--;J=SA[RANK[I]-1];WHIle (Str[i+k]==str[j+k]) k++;height[rank[i]]=k;} int mm[maxn];int best[20][maxn];void INITRMQ (int n) {mm[0]=-1;for (int i=1;i<=n;i++) mm[i]= ((i& (i-1)) ==0?mm[i-1 ]+1:MM[I-1]); for (int i=1;i<=n;i++) best[0][i]=i;for (int. i=1;i<=mm[n];i++) {for (int j=1;j+ (1<<i) -1<=n ; j + +) {int A=best[i-1][j];int b=best[i-1][j+ (1<< (i-1))];if (Height[a]
Spoj SUBST1 POJ 2406 POJ REPEATS suffix Array Summary