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

来源:互联网 发布:2016广联达软件购买 编辑:程序博客网 时间:2024/05/17 06:17

存个模板

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<string>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 200000;string s;int sa[MAXN+10], Rank[MAXN+10], tmp[MAXN+10], top[MAXN+10];int n;bool CMP(int i, int k, int *y) {if(y[sa[i]] != y[sa[i-1]]) return false;if(sa[i] + k >= n || sa[i-1] + k >= n) return false;return y[sa[i]+k] == y[sa[i-1]+k];}void GetSA(int m) {int *x = Rank, *y = tmp;for(int i = 0; i < m; i++) top[i] = 0;for(int i = 0; i < n; i++) top[x[i] = s[i]]++;for(int i = 1; i < m; i++) top[i] += top[i-1];for(int i = n-1; i >= 0; i--) sa[--top[x[i]]] = i;for(int k = 1; k <= n; k <<= 1) {int p = 0;for(int i = n-k; i < n; i++) y[p++] = i;for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k;for(int i = 0; i < m; i++) top[i] = 0;for(int i = 0; i < n; i++) top[x[y[i]]]++;for(int i = 1; i < m; i++) top[i] += top[i-1];for(int i = n-1; i >= 0; i--) sa[--top[x[y[i]]]] = y[i];swap(x, y);p = 1; x[sa[0]] = 0;for(int i = 1; i < n; i++)x[sa[i]] = CMP(i, k, y) ? p-1 : p++;if(p >= n) break;m = p;}}int main() {cin >> s;s += s;n = s.length();GetSA(255);for(int i = 0; i < n; i++)if(sa[i] < (n >> 1))putchar(s[sa[i]+(n>>1)-1]);}


0 0