字尾陣列學習與應用

2021-08-19 21:47:00 字數 2258 閱讀 8436

sa[i]:即,排名為i的字尾的起點下標

rank[i]:即,第i個字尾的排名

height[i]:即,sa[i]和sa[i-1]的最長公共字首

h[i]:即,height[rank[i]],即第i個字尾與前一名的最長公共字首

結論一:

定義:lcp

(i,j

)=lc

p(su

ffix

(sa[

i],s

uffi

x(sa

[j])

l cp

(i,j

)=lc

p(su

ffix

(sa[

i],s

uffi

x(sa

[j])

則轉化:lc

p(i,

j)=m

in(h

eigh

t[k]

) lcp

(i,j

)=mi

n(he

ight

[k])

,sa[i]+1≤k≤sa[j]

結論二:

suffix[i]的與其他字尾的最長公共字首為ma

x(he

ight

[sa[

i]],

heig

ht[s

a[i]

+1])

m ax

(hei

ght[

sa[i

]],h

eigh

t[sa

[i]+

1])結論三: h[

i]h [i

]≥h[

i−1]

−1h [i

−1]−

1,理由suffix[i-1]去掉乙個字元後的suffix[i],必然存在另乙個字尾也去掉相同字元後的的匹配長度為h[i-1]-1;由結論二可知,h[

貼乙份好部落格

poj2774

題意:問兩個字串的最長公共子串

題解:兩個字串拼接,中間用特殊字元隔開,然後字尾陣列模版,詳見**

#include

#include

#include

#include

using

namespace

std;

const

int maxn=200005;

int a[maxn];//

int sa[maxn],height[maxn],rank[maxn],tax[maxn],y[maxn];

//sa[i]排名為i的字尾的起始下標;rank[i]起始下標為i的字尾的排名;

//height[i]排名為i的字尾和前一名的lcp;tax[i]輔助計數排序,記錄的是排名為i的個數,它維護乙個字首

//y[i]維護的是第二關鍵字 ,表示排名為i的是那個第二關鍵字與第y[i]個第一關鍵字組合排序

int n,m;//n為字串長度,m為ascii碼個數,也是排名種數。

void rsort()

int cmp(int *f, int x, int y, int w)

void suffix()

//計算lcp

int k=0,j;

for(int i=1; i<=n; height[rank[i++]]=k)

for(k=(k?k-1:k),j=sa[rank[i]-1]; (i+k)<=n&&(j+k)<=n&&a[i+k]==a[j+k]; k++);

//通過我們的結論h[i]>=h[i-1]-1;可知我們設k=h[i-1]-1;那麼下一次匹配時只需從 a[i+k]==a[j+k]開始比較

}char str[maxn],str1[maxn];

int l1,l2;

void init()

a[l1+1]=128;

for(int i=0; i2]=str1[i];

}n=l1+l2+1;

}int main()

}printf("%d\n",ans);

return

0;}

字尾陣列的應用

本文參考了 字尾陣列 處理字串的有力工具 子串 字串s 的子串r i.j i j,表示r 串中從i 到j 這一段,也就是順次排列r i r i 1 r j 形成的字串。字尾 字尾是指從某個位置i 開始到整個串末尾結束的乙個特殊子串。字串r 的從第i 個字元開始的字尾表示為suffix i 也就是 s...

字尾陣列的應用

1.求乙個字串所有不同的子串個數 子串意味著是連續的 比如 abaaba 它的字串包括 a,b,aa,ab,ba,aba,baa,aab,abaa,baab,aaba,abaab,baaba,abaaba。這個就可以用字尾陣列的結果求解。首先,我們知道sa陣列,裡面是排好序的所有字尾,運用字尾的想法...

字尾樹與字尾陣列

字尾樹和字尾陣列是字串處理的兩大神器,幾乎可處理掉一切的字串處理問題,但是在實際中,字尾陣列比字尾樹更好寫 好調,同時時間上也不差 常數很小 所以字尾陣列絕對是oi競賽之必備神器。字尾樹,實際上就是一棵字典樹。考慮將某個串 s 的所有字尾插到一棵trie裡,那麼我們就得到了一棵字尾樹。在這裡,我們不...