CF1676F Longest Strike 题解

题意

给你一个长度为 n 的序列 a 和一个整数 k,你要求一个区间 [l,r] 满足:

  • 对于任何整数 x[l,r]xa 中的出现次数不少于 k 次。
  • 最大化 rl

无解输出 -1

思路

看到出现次数,先把 a 装进桶 c 里,

发现装不进去,就离散化一下再装进桶 c 里。

l,r 存正在处理的区间,x,y 存目前最大的区间,s 存目前最大区间的大小。

接着按离散化后的 ai 从小到大扫一遍:

  • 如果 cik,区间可以包含 ai,则 rai
    1. 如果 aiai1+1,不能与之前的区间接上,则“另起炉灶”,lai
    2. 否则 l 保持原值不变。
    3. l,r 更新 x,y,s
  • 否则区间不能包含 ailai+1,rai+1

注意这里 a1 必须“另起炉灶”,因为 a1 之前没有别的区间。

所以我们要手动让 a1a0+1a01 即可。

最后如果 s 从未被更新过就是无解,否则解为 [x,y]

代码

#include <cstdio>
#include <algorithm>
#define h(x) lower_bound(a + 1, a + m + 1, x) - a
using namespace std;
int T, n, m, k, s, l, r, x, y, a[200050], b[200050], c[200050];
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &k);s = -1;
        for(int i = 1;i <= n;++i) scanf("%d", &a[i]), b[i] = a[i];
        sort(a + 1, a + n + 1);m = unique(a + 1, a + n + 1) - a - 1;
        for(int i = 1;i <= m;++i) c[i] = 0;
        for(int i = 1;i <= n;++i) ++c[h(b[i])];a[0] = -1;
        for(int i = 1;i <= m;++i)
            if(c[i] >= k)
            {
                if((r = a[i]) != a[i - 1] + 1) l = a[i];
                if(r - l > s) s = r - l, x = l, y = r;
            }
            else l = r = a[i + 1];
        if(s == -1) puts("-1");
        else printf("%d %d\n", x, y);
    }
    return 0;
}
posted @   Jijidawang  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示