- #include <iostream>
- #include <string>
- #include <algorithm>
- using namespace std;
- #define Min(a,b) (a)<(b)?(a):(b)
- const int N = 2000;
- const int D = 10;
- const int M = 260;
- int n;
- char s[N] = "abcabdeabf";
- int cnt[N], mem[4][N], *rank, *nrank, *sa, *nsa, lcp[20][N];
- // lcp[i][j]: longest commen prefix ( suffix(sa[k+1]), suffix(sa[k]) ) j <= k < j+2^i
- void suffix()
- {
- int i, j, k;
- rank = mem[0];
- nrank = mem[1];
- sa = mem[2];
- nsa = mem[3];
- for(i = 0; i < n; i++) cnt[s[i]]++;
- for(i = 1; i < M; i++) cnt[i] += cnt[i-1];
- for(i = n-1; i >= 0; i--) sa[--cnt[s[i]]] = i;
- for(rank[0]=0, i=1; i < n; i++)
- {
- rank[sa[i]] = rank[sa[i-1]];
- if(s[sa[i]]!=s[sa[i-1]]) rank[sa[i]]++;
- }
- for(k = 1; k<n && rank[sa[n-1]] < n-1; k*=2)
- {
- for(i = 0; i < n; i++) cnt[rank[sa[i]]] = i+1;
- for(i = n-1; i >= 0; i--) if(sa[i]-k>=0)
- nsa[--cnt[rank[sa[i]-k]]] = sa[i]-k;
- // max(sa[i]-k)=n-k-1 , therefore i = n-k;
- for(i = n-k; i < n; i++)
- nsa[--cnt[rank[i]]] = i;
- for(nrank[nsa[0]], i=1; i < n; i++)
- {
- nrank[nsa[i]] = nrank[nsa[i-1]];
- if(rank[nsa[i]] != rank[nsa[i-1]]
- || rank[nsa[i]+k] != rank[nsa[i-1]+k])
- nrank[nsa[i]]++;
- }
- swap(rank, nrank);
- swap(sa, nsa);
- }
- }
- void print()
- {
- for(int i=0;i<n;i++) printf("%d %s/n", sa[i], s + sa[i]);puts("");
- puts(s);for(int i=0;i<n;i++) printf("%d ", rank[i]);puts("");
- }
- void get_lcp_rmq()
- {
- int i, j, k;
- for(i=0,k=0; i<n; i++)
- {
- if(rank[i]==n-1) lcp[0][rank[i]]=k=0;
- else
- {
- if(k>0)k--;
- j = sa[rank[i]+1];
- for(;s[i+k]==s[j+k];k++) ;
- lcp[0][rank[i]]=k;
- }
- }
- for(i=0,k=1; k<n; k*=2, i++)
- {
- for(j = 0; j+k < n; j++)
- lcp[i+1][j] = Min(lcp[i][j], lcp[i][j+k]);
- }
- }
- int rmq(int a, int b)
- {
- int i, j, k;
- if(a==b) return n-1-a;
- a = rank[a];
- b = rank[b];
- if(a>b) swap(a,b);
- int t=b-a;
- for(i=0,k=1; 2*k<t; i++,k*=2) ;
- return Min(lcp[i][a], lcp[i][b-k]); // not b-k+1
- // lcp[0][i]: LCP(i,i+1)
- }
- int main()
- {
- int i, j, k;
- n = strlen(s);
- s[n++]=0;
- memset(cnt, 0, sizeof(cnt));
- memset(mem, 0, sizeof(mem));
- suffix();
- print();
- get_lcp_rmq();
- printf("%d/n", rmq(2,3));
- return 0;
- }
后缀数组
最新推荐文章于 2025-05-27 00:18:58 发布
3007





