首页 > 代码库 > [BZOJ1031][JSOI2007]字符加密Cipher(后缀数组)

[BZOJ1031][JSOI2007]字符加密Cipher(后缀数组)

传送门

 

算是个模板。

题目说循环,那就再复制一串拼接上。

然后求后缀数组,再搞就可以。

 

虽然是求后缀,会在后面多一些字符串,然而题目中说的是循环一圈,但是没有影响。

 

——代码

技术分享
 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 200005 5  6 int m = z + 1; 7 int len, buc[N], x[N], y[N], sa[N]; 8 char s[N]; 9 10 inline void build_sa()11 {12     int i, k, p;13     for(i = 0; i < m; i++) buc[i] = 0;14     for(i = 0; i < len; i++) buc[x[i] = s[i]]++;15     for(i = 1; i < m; i++) buc[i] += buc[i - 1];16     for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;17     for(k = 1; k <= len; k <<= 1)18     {19         p = 0;20         for(i = len - 1; i >= len - k; i--) y[p++] = i;21         for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;22         for(i = 0; i < m; i++) buc[i] = 0;23         for(i = 0; i < len; i++) buc[x[y[i]]]++;24         for(i = 1; i < m; i++) buc[i] += buc[i - 1];25         for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];26         std::swap(x, y);27         p = 1, x[sa[0]] = 0;28         for(i = 1; i < len; i++)29             x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;30         if(p >= len) break;31         m = p;32     }33 }34 35 int main()36 {37     int i;38     scanf("%s", s);39     len = strlen(s);40     for(i = len; i < (len << 1); i++) s[i] = s[i - len];41     len <<= 1;42     build_sa();43     len >>= 1;44     for(i = 0; i < (len << 1); i++)45         if(sa[i] < len)46             printf("%c", s[sa[i] + len - 1]);47     return 0;48 }
View Code

 

[BZOJ1031][JSOI2007]字符加密Cipher(后缀数组)