Http://acm.hdu.edu.cn/showproblem.php?
pid=4691
Last summer, more school races were titled. At that time, there was no suffix array
Today will be, in fact, its own suffix array combination rmq or to, but, test instructions understand a problem, and then toss it for a long time,,,
Here is a brief explanation of the topic, hoping to help the reader to take the last set of data as an example
Myxophytamyxopodnabnabbednabbingnabit
6
2 {
9 16
16 19
19 25
25 32
32 37
The first two lines do not explain, the topic is very clear
From the third line, 0 9 refers to the first string that is from the first line of the string 0-9 left and right open,
The following 5 lines are also
Continue to look at the examples of the main body of the topic
Then the first one after compression is "0 spaces and the first 9 characters plus a newline" altogether 12. The following lines are the same algorithm
Note that if the public prefix length is 24, then two cells are stored, which is what I wrote the Weishu function.
On the code:
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include < Algorithm> #include <cmath>using namespace std;const int MAXN =100000+20;int N,k;//n=strlen (s); int RANK[MAXN], Tmp[maxn],d[maxn],st[maxn][20],lcp[maxn],sa[maxn];char s[maxn];/* uses rank to sort the SA */bool cmpsa (int i, int j) {if (Rank[i]! = RANK[J]) return rank[i] < RANK[J]; else {/* Rank[t], is already at the beginning of t length less than or equal to K/2. Sa[i], only the suffix that begins with I, and the length is different */int ri = I+k <=n? Rank[i+k]:-1; int RJ = J+k <= n? Rank[j+k]:-1; Return RI <rj; }}/* Compute sa*/void Consa (char *s, int *sa) {for (int i=0;i<=n;i++) {sa[i]=i; Rank[i] = i < n?s[i]:-1; k=1;k<=n;k*=2/* Note that in this code k is a global variable, and the loop must start at 1 due to 0*2=0*/{sort (SA,SA+N+1,CMPSA); Tmp[sa[0]] = 0; /* At this time TMP is only staged rank*/for (int i=1;i<=n;i++) {Tmp[sa[i]] = Tmp[sa[i-1]] + (CMPSA (sa[i-1],sa[i))? 1:0); } for (int i=0;i<=n;i++) {Rank[i] = tMp[i]; }}}void CONSTRUCT_LCP (char *s,int *sa,int *LCP) {//n=strlen (s); for (int i=0; i<=n; i++) rank[sa[i]]=i; int h=0; lcp[0]=0; for (int i=0;i<n;i++) {int j=sa[rank[i]-1]; if (h>0) h--; for (; J+h<n && i+h<n; h++) {if (s[j+h]!=s[i+h]) break; } lcp[rank[i]-1]=h; }}void initrmq (int nn) {int i,j; for (d[0]=1,i=1;i<21;i++) d[i]=2*d[i-1]; for (i=0;i<nn;i++) st[i][0]=lcp[i]; for (int i=0;i<nn;i++)//{//printf ("%s i=%d sa=%d rank=%d lcp=%d\n", s+sa[ I],i,sa[i],rank[i],lcp[i]); printf ("| | | | | | | | | %s lcp[rank]=%d\n ", S+i,lcp[rank[i]]); }////////////////////////////////int K=int (log (double (NN))/log (2.0) +1); for (j=1;j<k;j++) for (i=0;i<nn;i++) {if (I+D[J-1]-1<NN) {St[i] [J]=min (St[i][j-1],st[i+d[j-1]][j-1]); } else break; }}iNT Weishu (int n) {if (n<10) return 1; int ans=0; while (n) {n/=10; ans++; } return ans; int main () {//freopen ("Hdu4691.txt", "R", stdin); Long Long Ansb,ansa; int KK; while (~SCANF ("%s", s)) {ansb=ansa=0; N=strlen (s); Consa (S,SA); CONSTRUCT_LCP (S,SA,LCP); INITRMQ (n+1); int num,l,r,x,y; scanf ("%d", &num); int last=0,lastlen=0; scanf ("%d%d", &l,&r); ansb+=r-l+1; ansa+=r-l+3; Lastlen=r-l; Last=l; for (int i=1;i<num;i++) {scanf ("%d%d", &l,&r); ansb+=r-l+1; Ansa+=r-l; X=min (Rank[last],rank[l]), Y=max (Rank[last],rank[l])-1; KK = Int (log (double (y-x+1))/log (2.0)); int ret; if (L = = last) ret=n-l; else Ret=min (St[x][kk], St[y-d[kk]+1][kk]); Ret=min (ret, min (lastlen,r-l)); Ansa =ansa-ret+weishu (ret) +2; Last=l; Lastlen=r-l; } printf ("%i64d%i64d\n", Ansb,ansa); } return 0;}
Add a rmq+ suffix array for the longest common prefix template bar
(In fact, there is no test, the problem is tested)
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include < Algorithm> #include <cmath>using namespace std;const int MAXN =100000+20;int N,k;//n=strlen (s); int RANK[MAXN], Tmp[maxn],d[maxn],st[maxn][20],lcp[maxn],sa[maxn];char s[maxn];/* uses rank to sort the SA */bool cmpsa (int i, int j) {if (Rank[i]! = RANK[J]) return rank[i] < RANK[J]; else {/* below rank[t], is already a position with a length less than or equal to K/2, Sa[i]. is only the suffix beginning with I, and the length is different */int ri = I+k <=n? Rank[i+k]:-1; int RJ = J+k <= n? Rank[j+k]:-1; Return RI <rj; }}/* Compute sa*/void Consa (char *s, int *sa) {for (int i=0;i<=n;i++) {sa[i]=i; Rank[i] = i < n?s[i]:-1; k=1;k<=n;k*=2/* Note that in this code k is a global variable and the loop must start at 1. Due to 0*2=0*/{sort (SA,SA+N+1,CMPSA); Tmp[sa[0]] = 0; /* At this time TMP is only staged rank*/for (int i=1;i<=n;i++) {Tmp[sa[i]] = Tmp[sa[i-1]] + (CMPSA (sa[i-1],sa[i))? 1:0); } for (int i=0;i<=n;i++) {Rank[i] = tMp[i]; }}}void CONSTRUCT_LCP (char *s,int *sa,int *LCP) {//n=strlen (s); for (int i=0; i<=n; i++) rank[sa[i]]=i; int h=0; lcp[0]=0; for (int i=0;i<n;i++) {int j=sa[rank[i]-1]; if (h>0) h--; for (; J+h<n && i+h<n; h++) {if (s[j+h]!=s[i+h]) break; } lcp[rank[i]-1]=h; }}void initrmq (int nn) {int i,j; for (d[0]=1,i=1;i<21;i++) d[i]=2*d[i-1]; for (i=0;i<nn;i++) st[i][0]=lcp[i]; int K=int (log (double (NN))/log (2.0) +1); for (j=1;j<k;j++) for (i=0;i<nn;i++) {if (I+D[J-1]-1<NN) {St[i] [J]=min (St[i][j-1],st[i+d[j-1]][j-1]); } else break; }}int ANSLCP (int a, int b) {int KK; if (a = = B) Return n-a;//n is the length of the entire string x=min (Rank[a],rank[b]), Y=max (Rank[a],rank[b])-1; KK = Int (log (double (y-x+1))/log (2.0)); return min (St[x][kk], St[y-d[kk]+1][kk]);} int Query (int Q)//q times ask {int ans; for (iNT i=0;i<q;i++) {scanf ("%d%d", &a,&b); ANS=ANSLCP (A, b); }}
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
HDU 4691 longest common prefix suffix array +lcp+rmq