洛谷P2852 [USACO06DEC]Milk Patterns G 题解 后缀数组height数组的应用
题目链接:https://www.luogu.com.cn/problem/P2852
题目大意:
求数列中出现次数至少为 次的连续子序列的最大长度。
解题思路:
可以转成对 数组求 (区间长度为 的区间最小值 的 最大值)。用单调队列解决。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int n, k, w, sa[maxn], rk[maxn], oldrk[maxn<<1], height[maxn];
int s[maxn];
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", s+i);
for (int i = 1; i <= n; i++) sa[i] = i, rk[i] = s[i];
for (w = 1; w < n; w <<= 1) {
sort(sa+1, sa+n+1, [](int i, int j) {
return rk[i] == rk[j] ? rk[i + w] < rk[j + w] : rk[i] < rk[j];
});
memcpy(oldrk, rk, sizeof(int)*(n+1));
for (int i = 1, p = 0; i <= n; i++) {
if (oldrk[sa[i]] != oldrk[sa[i-1]] || oldrk[sa[i] + w] != oldrk[sa[i-1] + w])
p++;
rk[sa[i]] = p;
}
}
for (int i = 1, k = 0; i <= n; i++) {
if (!rk[i]) continue;
if (k) k--;
while (s[i + k] == s[sa[rk[i] - 1] + k]) k++;
height[rk[i]] = k;
}
deque<int> que;
int ans = 0;
for (int i = 1; i <= n; i++) {
while (!que.empty() && height[que.back()] >= height[i]) que.pop_back();
if (!que.empty() && que.front() <= i - k + 1) que.pop_front();
que.push_back(i);
if (i >= k) ans = max(ans, height[que.front()]);
}
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-03-03 AtCoder Beginner Contest 047 题解
2021-03-03 AtCoder Beginner Contest 046 题解
2021-03-03 AtCoder Beginner Contest 045 题解
2020-03-03 洛谷P5016 龙虎斗 题解 简单模拟
2020-03-03 洛谷P5684 非回文串 题解 组合数学的另一种解法
2020-03-03 洛谷P5682 次大值 题解