欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > javascript >内容正文

javascript

bzoj 1031 [JSOI2007]字符加密Cipher 后缀数组

发布时间:2024/6/30 javascript 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 bzoj 1031 [JSOI2007]字符加密Cipher 后缀数组 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题面

题目传送门

解法

后缀数组模板题吧……

将字符串两倍,然后求一遍sa数组即可

时间复杂度:\(O(n\ log\ n)\)

代码

#include <bits/stdc++.h> #define N 200010 using namespace std; char st[N]; int len; struct SuffixArray {int x[N], y[N], sa[N], cnt[N];void getsa() {int n = strlen(st + 1), m = 200;for (int i = 1; i <= n; i++) st[i + n] = st[i]; n *= 2;for (int i = 1; i <= n; i++) cnt[x[i] = st[i]]++;for (int i = 2; i <= m; i++) cnt[i] += cnt[i - 1];for (int i = n; i; i--) sa[cnt[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1) {int num = 0;for (int i = n - k + 1; i <= n; i++) y[++num] = i;for (int i = 1; i <= n; i++)if (sa[i] > k) y[++num] = sa[i] - k;for (int i = 1; i <= m; i++) cnt[i] = 0;for (int i = 1; i <= n; i++) cnt[x[i]]++;for (int i = 2; i <= m; i++) cnt[i] += cnt[i - 1];for (int i = n; i; i--) sa[cnt[x[y[i]]]--] = y[i], y[i] = 0;swap(x, y); x[sa[1]] = 1, num = 1;for (int i = 2; i <= n; i++)x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? num : ++num;if (n == num) break; m = num;}}void solve() {int n = strlen(st + 1);for (int i = 1; i <= n; i++) {int x = sa[i];if (x <= len) cout << st[x + len - 1];}cout << "\n";} } SA; int main() {scanf(" %s", st + 1);len = strlen(st + 1);SA.getsa(); SA.solve(); return 0; }

转载于:https://www.cnblogs.com/copperoxide/p/9478372.html

总结

以上是生活随笔为你收集整理的bzoj 1031 [JSOI2007]字符加密Cipher 后缀数组的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。