描述
字尾陣列 (sa) 是一種重要的資料結構,通常使用倍增或者dc3演算法實現,這超出了我們的討論範圍。在本題中,我們希望使用快排、hash與二分實現乙個簡單的 o(n log^2n ) 的字尾陣列求法。詳細地說,給定乙個長度為 n 的字串s(下標 0~n-1),我們可以用整數 k(0≤k
輸入格式
乙個字串,長度不超過30萬。
輸出格式
第一行為陣列sa,相鄰兩個整數用1個空格隔開。
第二行為陣列height,相鄰兩個整數用1個空格隔開,特別地,假設height[1]=0。
樣例輸入
ponoiiipoi樣例輸出
9 4 5 6 2 8 3 1 7 0樣例解釋0 1 2 1 0 0 2 1 0 2
排名第一(最小)的字尾是9(s[9~9],即字串 i),第二的是字尾4(s[4~9],即字串iiipoi),第三的是字尾5(s[5~9],即字串iipoi)以此類推。height[2]表示排名第2與第1的字尾的最長公共字首,長度為1,height[3]表示排名第3與第2的字尾的最長公共字首,長度為2,以此類推。
思路:因為要按照字典序排序,既然排序,那麼就想到了快排sort。
那就要自定義比較函式,如果對於兩個字串o(n)掃瞄比較,那麼總體複雜度o(n2logn)
我們可以二分比較的長度,對於同樣長的字串通過對字串hash得到的hash值比較其是否相同,o(logn)找出其不同位置,然後比較該位置大小,這樣複雜度o(nlog2n)
#includeusingview codenamespace
std;
const
int maxn = 1000005
;unsigned
long
long
f[maxn],p[maxn];
char
word[maxn];
intn;
struct
node
} node[maxn];
unsigned
long
long getf(int l,int
r)int
cal(node a,node b)
else
}return l-1;}
bool
cmp(node a,node b)
intmain()
sort(node+1,node+1+n,cmp);
for(int i=2; i<=n; i++)
for(int i=1; i<=n; i++)
for(int i=1; i<=n; i++)
}
AcWing 140 字尾陣列 hash 二分
題目大意 給乙個字串,假設長度為n,那麼它就有n個字尾,求排名為i的字典序,並求出排序中相鄰串的最長公共字首。題解 hash 二分 假設字串從1開始 如果將n個字尾字串用sort排序,需要比較nlogn次,每次比較最差需要o n 所以時間複雜度為o n 2logn 考慮將o n 的比較用二分優化為l...
poj1743(字尾陣列 二分)
不可重疊最長重複子串 字尾陣列後,二分最長長度,在維護長度不小於mid時,判斷是否有兩個位置之間的差 mid,表示不重疊,由此更新l,r 方法 字串處理常用二分 字尾陣列常用分組 分組的本質就是這個組均包含長度為mid的子串,就是這個組的長度為mid的字首都相同 include include in...
poj1745 字尾陣列 二分
題目大意 求最長的不重疊重複字串的最大值 思路 二分最長的長度l,然後按照height l分組,可以得出每乙個l都會在同一組內,而這組sa i max sa i min l 則成立 這題輸入的細節比較多需要注意 我會說我t了 include include include include inclu...