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裡,那麼我們就得到了一棵字尾樹。在這裡,我們不...