字尾陣列模板詳解。

2021-08-04 14:46:06 字數 1460 閱讀 7419

給定乙個字串s,比如它是(abcad),那麼它的字尾有」abcad「  ,"bcad ", "cad",  "ad", "d", ""。 講這些字尾字串按照字典序排序,得到的就是字尾陣列。如果用普通的排序方法,排序要o(nlogn),但是每兩個字元比較大小要o(n),所以是o(n × n log n)的複雜度。但是利用特殊的演算法可以將其降到o(nlogn)。 

該演算法的思想是,先將每個字尾陣列按照只考慮頭乙個字元,排序, 再將其按照只考慮頭兩個字元排序,然後是頭4個,然後是8個,直到考慮n個。

#include #include #include #include using namespace std;

#define max_n (200000 + 100)

int n;

int k;

int rank1[max_n], tmp[max_n];

int sa[max_n];// n為字元長度, rank1[[i] 表示的是以第i個字元開頭的字尾陣列的排名, sa[i] 是排在i位的字尾陣列的開頭字元的位置。

bool compare_sa(int i, int j)

}void construct_sa(string buf)

for ( k = 1; k <= n; k *= 2)

for (int i = 0; i <= n; i++) }}

int main()

cout << endl;

for (int i = 0; i <= n; i++)

return 0;

}

cd3演算法,沒怎麼理解, 所以只能照敲了模板,儲存一發。

cd3的演算法雖然是線性的o(n) 的,但是其前面的常數特別大而且會占用大量記憶體,相對於倍增演算法的o(nlogn)優勢也不是很大,只要題目不是特別特殊,倍增演算法都可以解決。

#include #include #include #include using namespace std;

#define max_n 1000

#define f(x) ((x)/3+((x)%3==1?0:tb))

#define g(x) ((x)= 0; i--) b[--ws1[wv1[i]]] = a[i];

return;

}void dc3(int *r, int *sa, int n, int m)

// str sa 都要開三倍的;

void da(int str, int sa, int rank1, int height1, int n, int m)

return;

}int str[3*max_n];

int sa[3*max_n];

int rank1[3*max_n];

int height1[3*max_n];

int main()

字尾陣列倍增演算法模板詳解

2009國家集訓隊 字尾陣列 處理字串的有力工具 羅穗騫 bool cmp int r,int a,int b,int l void init int r,int sa,int n,int m for i 0 i n i rk sa i i int k 0 for i 0 i n 1 h rk i ...

字尾陣列 模板

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