[luoguP2870] [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(后缀数组)
Posted 蒟蒻zht的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2870] [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(后缀数组)相关的知识,希望对你有一定的参考价值。
数据小的话贪心就行。
可以把这个串翻转再接到后面,再求后缀数组,求出 rank 数组就很简单了。
——代码
1 #include <cstdio> 2 #include <iostream> 3 #define N 60001 4 5 int n, len, m = 256, sum; 6 int buc[N], x[N], y[N], sa[N], rank[N]; 7 char s[N]; 8 9 inline void build_sa() 10 { 11 int i, k, p; 12 for(i = 0; i < m; i++) buc[i] = 0; 13 for(i = 0; i < len; i++) buc[x[i] = s[i]]++; 14 for(i = 1; i < m; i++) buc[i] += buc[i - 1]; 15 for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i; 16 for(k = 1; k <= len; k <<= 1) 17 { 18 p = 0; 19 for(i = len - 1; i >= len - k; i--) y[p++] = i; 20 for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k; 21 for(i = 0; i < m; i++) buc[i] = 0; 22 for(i = 0; i < len; i++) buc[x[y[i]]]++; 23 for(i = 1; i < m; i++) buc[i] += buc[i - 1]; 24 for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i]; 25 std::swap(x, y); 26 p = 1, x[sa[0]] = 0; 27 for(i = 1; i < len; i++) 28 x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++; 29 if(p >= len) break; 30 m = p; 31 } 32 } 33 34 int main() 35 { 36 int i, l, r; 37 scanf("%d", &n); 38 len = n * 2; 39 for(i = 0; i < n; i++) getchar(), s[i] = getchar(), s[len - i - 1] = s[i]; 40 build_sa(); 41 for(i = 0; i < len; i++) rank[sa[i]] = i; 42 l = 0, r = n - 1; 43 while(l <= r) 44 { 45 if(rank[l] <= rank[len - r - 1]) putchar(s[l++]); 46 else putchar(s[r--]); 47 if(++sum == 80) sum = 0, putchar(‘\n‘); 48 } 49 return 0; 50 }
以上是关于[luoguP2870] [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章
P2870 [USACO07DEC]Best Cow Line G
P2870 [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold
[Luogu2870] [USACO07DEC]最佳牛线Best Cow Line(贪心+后缀数组)
P2870 [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold