1402 字尾陣列 (hash 二分)

2022-08-01 04:06:13 字數 1345 閱讀 5355

描述

字尾陣列 (sa) 是一種重要的資料結構,通常使用倍增或者dc3演算法實現,這超出了我們的討論範圍。在本題中,我們希望使用快排、hash與二分實現乙個簡單的 o(n log^2⁡n ) 的字尾陣列求法。詳細地說,給定乙個長度為 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)

#includeusing

namespace

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++)

}

view code

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...