字尾陣列模板

2021-09-25 04:42:56 字數 2628 閱讀 2547

sa[

i]=j

:sa[i]=j:

sa[i]=

j:表示第i

ii小的字尾是從第j

jj個位置開始的字尾

r an

k[i]

=j

:rank[i]=j:

rank[i

]=j:

表示從第i

ii個位置開始的字尾是第jjj小

h ei

ght[

i]=j

:height[i]=j:

height

[i]=

j:表示在字尾陣列中第i

ii小和第i−1

i-1i−

1小的字尾的最長公共字首

h [i

]=he

ight

[ran

k[i]

]h[i]=height[rank[i]]

h[i]=h

eigh

t[ra

nk[i

]]:h

hh陣列在本質上是hei

gh

theight

height

陣列,只不過h

hh陣列在[0,

n−1]

[0,n-1]

[0,n−1

]的順序下面是計算從第i

ii個位置開始的字尾和排在這個字尾前面的乙個字尾的lcp

lcplc

p。而hei

gh

theight

height

陣列是計算次序為i

ii的字尾和排在這個字尾前面的乙個字尾的lcp

lcplc

p。由於常規計算height陣列最壞複雜度是n^2的,所以引入了h陣列,目的在於減少複雜度,因為h陣列給height陣列賦值是跳著賦值的,而不是按照[0,n]的順序賦值的。

//快排寫法

int n, k;

int rank[maxn +1]

;//記錄下長度為k的子串的相對大小

int tmp[maxn +1]

;int sa[maxn]

;//字尾陣列

string s;

//長度為k時,對sa進行比較

//如果rank[i]!=rank[j],那說明在前半段,s[i..]就比s[j..]大.

//如果相等,就比較後半段.

bool compare_sa

(int i,

int j)

//如果以i開始,長度為k的字串的長度,已經超出了字串尾,那麼就賦值為-1

//這是因為,在前面所有資料相同的情況下,字串短的字典序小.

int ri = i + k <= n ? rank[i + k]:-

1;int rj = j + k <= n ? rank[j + k]:-

1;return ri < rj;

}int

construct_sa()

for(k =

1; k <= n; k *=2

)for

(int i =

0; i <= n; i++)}

}

//基數排序寫法

const

int m =

1e6+5;

const

int maxn =

1e6+5;

//rnk從0開始

//sa從1開始,因為最後乙個字元(最小的)排在第0位

//height從1開始,因為表示的是sa[i - 1]和sa[i]

int wa[maxn]

, wb[maxn]

, wv[maxn]

, ws_[maxn]

;//suffix函式的引數m代表字串中字元的取值範圍,是基數排序的乙個引數,如果原序列都是字母可以直接取128,如果原序列本身都是整數的話,則m可以取比最大的整數大1的值

//待排序的字串放在r陣列中,從r[0]到r[n-1],長度為n

//為了方便比較大小,可以在字串後面新增乙個字元,這個字元沒有在前面的字元**現過,而且比前面的字元都要小

//同上,為了函式操作的方便,約定除r[n-1]外所有的r[i]都大於0,r[n-1]=0

//函式結束後,結果放在sa陣列中,從sa[0]到sa[n-1]

void

suffix

(int

*r,int

*sa,

int n,

int m)

}int rank[maxn]

, height[maxn]

, sa[maxn]

;int r[maxn]

;void

calheight

(int

*r,int

*sa,

int n)

for(i =

0; i < n; height[rank[i++]]

= k)

for(k ? k--:0

, j = sa[rank[i]-1

]; r[i + k]

== r[j + k]

; k++);

}

字尾陣列 模板

char s n 陣列的長度要為兩倍的 int n n全域性變數為字元陣列的長度的 int sa n 2 high n 2 rank n 2 tmp n 2 top n 2 void makesa void lcp int main gets s int len strlen s s len get...

字尾陣列模板

過了期末了,繼續寫acm題 自己寫的字尾陣列模板。k,len,rank,sa,tmp,都要寫在外面,這樣就不用來回折騰了。也是使用倍增法來做的,得到乙個sa,儲存了字尾排在第i位的字尾的起始位置。因為空也算乙個字尾,所以函式中都是 len include include include includ...

模板 字尾陣列

include include includeusing namespace std const int max 20001 int num max int sa max rank max height max int wa max wb max wv max wd max int cmp int ...