# BZOJ 1692: [Usaco2007 Dec]队列变换

g[i]表示从i开始，他的前缀(上面的例子 g[4] = CBAA  g[3]=BAA)

ABCD0DCBA

f[1]对应的串就是ABCD0DCBA  也就是rank[1]

g[4]对应的就是DCBA  也就是rank[6]

ACcode:   不优化380+ms  稍微优化了一点读入输出就跑到240+ms但是后缀数组写的不犀利没法到第一……

#include <cstdio>

const int max_n = 30000 * 2 + 10;
const int max_size = max_n * 1;

int n;
int sa[max_size], wa[max_size], wb[max_size];
int tong[max_size],wv[max_size];
char str[max_size];
int rank[max_size], h[max_size];

inline int cmp(int *r, int a, int b, int l)
{
return r[a] == r[b] && r[b+l]==r[a+l];
}

void da(char *r, int *sa, int n, int m)
{
int i,j,p, *x = wa, *y = wb, *t;
for (i = 0; i < m; ++ i)    tong[i] = 0;
for (i = 0; i < n; ++ i)    tong[x[i] = r[i]] ++;
for (i = 1; i < m; ++ i)    tong[i] += tong[i - 1];
for (i = n - 1; i >= 0; -- i)       sa[-- tong[x[i]]] = i;
for (j = 1, p =1; p < n; j *= 2, m = p)
{
for (p = 0, i = n - j; i < n; ++ i)   y[p ++] = i;
for (i = 0; i < n; ++ i) if (sa[i] >= j)   y[p ++] = sa[i] - j;
for (i = 0; i < m; ++ i) tong[i] = 0;
for (i = 0; i < n; ++ i) wv[i] = x[y[i]];
for (i = 0; i < n; ++ i) tong[wv[i]] ++;
for (i = 1; i < m; ++ i) tong[i] += tong[i - 1];
for (i = n - 1; i >= 0; -- i)   sa[--tong[wv[i]]] = y [i];
for (t =x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; ++ i)
x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)?p-1:p++;
}
}

inline void geth(char *r, int *sa, int n)
{
int i, j, k = 0;
for (i = 1; i <= n; ++ i)      rank[sa[i]] = i;
for (i = 0; i < n; h[rank[i ++]] = k)
for (k?k--:0, j = sa[rank[i] - 1]; r[i + k]==r[j + k]; ++ k);
}

char ch;
{
while (ch=getchar(),ch>'Z' || ch<'A') ;
x=ch;
}

int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++ i)      read(str[i]);
for (int i = 0; i < n; ++ i)      str[i] -= ('A' - 1);
str[n] = 0;
int tot = n * 2 + 1;
str[tot] = 0;
for (int i = 1; i <= n; ++ i)  str[n + i] = str[n - i];
da(str, sa, tot + 1, 28);
geth(str, sa, tot);
int A = 0, B = n + 1;
while (A + B - n - 1 < n)
{
if (rank[A] < rank[B])       putchar(str[A++] + 'A' - 1);
else putchar( str[B++] + 'A' - 1);
if (!((A + B - n - 1)%80))  putchar('\n');
}
return 0;
}


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客