首页 > 代码库 > [luoguP2870] [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(后缀数组)
[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(后缀数组)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。