給定乙個字串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...