1 条题解
-
0
自动搬运
来自洛谷,原作者为

Alex_Wei
**搬运于
2025-08-24 22:17:21,当前版本为作者最后更新于2022-07-02 18:50:30,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
因为字符不含 ,所以贪心让最大位数最小。答案串长度 。
答案满足可二分性。我们二分答案在后缀数组中的排名。破环成链,枚举 个起始点并判断是否可行。假设当前匹配到 ,若 的排名不大于二分的答案,那么就匹配 位,否则匹配 位。若进行 次匹配后总匹配位数不小于 则可行。
若可匹配 位时匹配 位,则下一次最多匹配 位,这与首先匹配 位时下一次匹配的最劣情况,即匹配 位,效果相同。因此贪心正确。
进一步地,比较两个长度为 的字符串时,我们不需要求 LCP 并比较下一个字符。可直接比较它们对应的后缀。问题在于也许 和 相等,其中 是排名为当前二分值的后缀开始位置,但 ,这使得我们认为只能匹配 位而非 位。
但其实没有关系,因为若 作为答案串可行,则二分排名最大的以 作为前缀的后缀时必然可行。
时间复杂度 。
#include <bits/stdc++.h> using namespace std; bool Mbe; constexpr int N = 4e5 + 5; int n, k, len; char s[N]; int rk[N], ork[N], sa[N], buc[N], id[N]; bool cmp(int a, int b, int w) {return ork[a] == ork[b] && ork[a + w] == ork[b + w];} void build() { int m = 1 << 7, p = 0; for(int i = 1; i <= n; i++) buc[rk[i] = s[i]]++; for(int i = 1; i <= m; i++) buc[i] += buc[i - 1]; for(int i = n; i; i--) sa[buc[rk[i]]--] = i; for(int w = 1; ; w <<= 1, m = p, p = 0) { for(int i = n - w + 1; i <= n; i++) id[++p] = i; for(int i = 1; i <= n; i++) if(sa[i] > w) id[++p] = sa[i] - w; memset(buc, 0, sizeof(buc)); memcpy(ork, rk, sizeof(rk)); p = 0; for(int i = 1; i <= n; i++) buc[rk[i]]++; for(int i = 1; i <= m; i++) buc[i] += buc[i - 1]; for(int i = n; i; i--) sa[buc[rk[id[i]]]--] = id[i]; for(int i = 1; i <= n; i++) rk[sa[i]] = cmp(sa[i - 1], sa[i], w) ? p : ++p; if(p == n) break; } } bool Med; int main() { fprintf(stderr, "%.4lf\n", (&Mbe - &Med) / 1048576.0); #ifdef ALEX_WEI freopen("1.in", "r", stdin); freopen("1.out", "w", stdout); #endif cin >> n >> k >> s + 1, len = (n - 1) / k + 1; for(int i = 1; i <= n; i++) s[i + n] = s[i]; n <<= 1, build(); int l = 1, r = n, m = n >> 1; while(l < r) { int mid = l + r >> 1, ok = 0; for(int i = 1; i <= len; i++) { int cur = 0; for(int j = 1; j <= k; j++) { int p = (i + cur - 1) % m + 1; if(rk[p] <= mid) cur += len; else cur += len - 1; } ok |= cur >= m; } if(ok) r = mid; else l = mid + 1; } for(int i = 0; i < len; i++) cout << s[sa[l] + i]; return cerr << "Time: " << clock() << "\n", 0; } /* 2022/7/2 start coding at 18:24 finish debugging at 18:36 */
- 1
信息
- ID
- 5123
- 时间
- 3000ms
- 内存
- 500MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者