当前位置: 首页 > news >正文

Codeforces Round 1054 (Div. 3) E题

题目
https://codeforces.com/problemset/problem/2149/E

题目复盘:恰好 K 个不同数字 + 长度限制的子数组计数

理解题目

我们有一个长度为 n 的数组,每个位置是一个整数。
现在要统计有多少个连续子数组,同时满足两个条件:

  1. 不同数字的个数恰好等于 k
  2. 子数组的长度在 [l, r] 之间

看到这种题,很容易就往双指针上想,方向是对的但是怎么实现呢?


难点在哪

如果只有“恰好 k 个不同数字”,滑动窗口可以直接维护左指针,保证窗口内不同数字个数 ≤ k,然后再想办法统计恰好为 k 的区间。

但现在多了一个长度限制 [l, r],窗口的大小不能再随意收缩:

  • 收缩过头,长度可能小于 l,不满足条件。
  • 扩张太多,长度可能超过 r,也不满足条件。

这意味着,对于固定的右端点 i,合法的左端点必须同时落在两个区间里


Hint:用“至多”表示“恰好”

经典套路:

恰好 k 个 = 至多 k 个 − 至多 (k−1) 个

为什么呢?

  • “至多 k 个”的区间集合,包含“恰好 k 个”和“不同数字少于 k 个”的区间。
  • “至多 k−1 个”的区间集合,只包含“不同数字少于 k 个”的区间。
  • 两者相减,剩下的就是“恰好 k 个”。

于是问题转化为:
统计每个右端点 i,有多少左端点 L 使得:

  1. [L, i] 内不同数字 ≤ k (集合 A)
  2. [L, i] 内不同数字 ≤ k−1 (集合 B)
  3. 长度在 [l, r] 之间

那么该右端点的贡献 = 同时满足条件 1 和长度限制的左端点位置 − (同时满足条件 2 和长度限制的左端点位置-1)。(不同数字恰好为 k,不能到 k - 1 所以为 ptr_k1-1)
即为当前右端点满足恰好为k的的合法贡献


双指针怎么移?

用两个滑动窗口,分别维护:

  • 窗口 A:不同数字 ≤ k
  • 窗口 B:不同数字 ≤ k−1

每个窗口都有一个左指针 ptr

  • 随着右端点 i 右移,新元素加入窗口。
  • 若窗口内不同数字个数超过了上限,就不断移动左指针,踢出元素,直到重新满足 ≤ 上限。

维护完成后:

  • 窗口 A 的左指针 ptr_k 表示:所有左端点 L ∈ [ptr_k, i],保证不同数字 ≤ k。
  • 窗口 B 的左指针 ptr_k1 表示:所有左端点 L ∈ [ptr_k1, i],保证不同数字 ≤ k−1。

那么“恰好 k 个不同数字”的左端点范围就是:

[ptr_k, ptr_k1 - 1]

(这里假设 ptr_k ≤ ptr_k1 - 1,否则不存在)


怎么再加上长度限制

对于右端点 i,子数组长度为 i - L + 1
要求 l ≤ i - L + 1 ≤ r,可以得出 L的范围:

i - r + 1 ≤ L ≤ i - l + 1

所以合法的 L 必须落在:

长度区间  = [i - r + 1, i - l + 1]
恰好k区间 = [ptr_k, ptr_k1 - 1]

两者取交集即可:

有效左端点下界 = max(ptr_k, i - r + 1)
有效左端点上界 = min(ptr_k1 - 1, i - l + 1)

如果下界 ≤ 上界,那么合法的左端点个数就是 上界 - 下界 + 1

这样,我们对每个 i 计算贡献,累加就得到答案。

我们很快就能给出代码:

点击查看代码
//
// Created by awake on 2026/5/13.
//https://codeforces.com/problemset/problem/2149/E
#include <bits/stdc++.h>
using namespace std;// clang-format off
struct { auto operator()(auto &i) { cin >> i; } } IN; // NOLINT
struct { auto operator()(auto &i) { cout << i << ' '; } } OUT; // NOLINT
// clang-format on
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr)// NOLINT
using pii = pair<int, int>; //NOLINT
using ll = long long;       //NOLINT
template <typename T>
using vec = vector<T>; //NOLINT
// #define int long long
// #define endl '\n'
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = 998244353;
constexpr int N = 1e6 + 5;void solve()
{int n, k, l, r;cin >> n >> k >> l >> r;vec<int> a(n);ranges::for_each(a, IN);map<int, int> cntk;map<int, int> cntk1;int ptr_k = 0;int ptr_k1 = 0;ll ans = 0;for (int i = 0; i < n; i++){cntk[a[i]]++;cntk1[a[i]]++;while (cntk.size() > k){if (cntk[a[ptr_k]]--; cntk[a[ptr_k]] == 0)cntk.erase(a[ptr_k]);ptr_k++;}while (cntk1.size() > k - 1){if (cntk1[a[ptr_k1]]--; cntk1[a[ptr_k1]] == 0)cntk1.erase(a[ptr_k1]);ptr_k1++;}int left_k = max(ptr_k, i - r + 1);int left_k1 = min(ptr_k1 - 1, i - l + 1);//[ptr_k, ptr_k1 - 1] (不同数字恰好为 k,不能到 k - 1 所以为 ptr_k1-1)//[i - r + 1, i - l + 1] (长度在 [l, r])if (left_k1 >= left_k)ans += left_k1 - left_k + 1;}cout << ans << endl;
}signed main()
{IOS;int T;cin >> T;while (T--)solve();return 0;
}

总结

这类“恰好 K 个 + 区间长度约束”的题目,核心思路分两步:

  1. 将“恰好”转化为“至多”的差值,化归为两个独立滑动窗口。
  2. 对每个右端点,找出多个约束区间的交集,利用单调性 O(1) 计算贡献。

掌握这个套路后,类似题(比如统计不同数字个数 ≤ K 且长度在某个范围)都能秒杀。

下次再遇到时,可以第一时间想到:

  • 双滑动窗口维护“至多”条件
  • 交集法合并长度限制
  • 差值法得到“恰好”的贡献
http://www.jsqmd.com/news/809791/

相关文章:

  • 2026年开封洛阳柴火鸡特色餐饮深度横评与选购指南 - 企业名录优选推荐
  • 2026年贵州柴火鸡特色餐饮选购指南:楠溪王捌鸡与行业竞品深度横评 - 企业名录优选推荐
  • 雨量监测站:实现降雨量实时精准计量
  • 张家口黄金回收哪家靠谱?金裕恒 / 盛誉轩 / 金成瑞连锁实测,无套路 - 润富黄金珠宝行
  • 在自动化Agent工作流中集成Taotoken实现多模型决策与调用
  • JPEGView:Windows上最轻量高效的图像查看与编辑解决方案
  • 2026年内墙仿石漆经销商靠谱吗:行业选型标准与主流品牌实力解析 - 产业观察网
  • 山东千宝再生资源:烟台工业原料回收企业哪个好 - LYL仔仔
  • 沧州卢辉再生物资回收:沧州光伏板回收生产厂家 - LYL仔仔
  • 当PID不够‘刚’时:用Simulink快速上手滑模控制(SMC)来搞定你的电机/机械臂模型
  • 2026年青岛广告投流与短视频代运营深度横评:极迅传媒如何破局企业获客困局 - 年度推荐企业名录
  • 2026年青岛广告投流与GEO推广一体化营销服务深度横评:如何精准获客 - 年度推荐企业名录
  • Information Fusion系统投稿流程
  • 2026年CRM厂商全景解析:五大通用型与工业版产品差异对比 - jfjfkk-
  • 手把手教你用C语言在粤嵌GEC6818开发板上显示任意BMP图片(附完整代码)
  • 2026最新工商注册公司排行:5家合规机构核心服务能力实测 - 奔跑123
  • 上海2026年柴火鸡土菜馆选购指南:从预制菜困局到原生态烟火气的突围之路 - 企业名录优选推荐
  • 联塑家装管属于什么档次,用过硬产品力解答管道品牌怎么选 - 极速运营
  • 基于RAG与LLM的智能股票研报生成系统:从数据到报告的工程实践
  • 河南洛阳柴火鸡2026年选购指南:5大品牌深度横评与土菜院子沉浸式体验对比 - 企业名录优选推荐
  • 百度网盘Mac版破解插件:简单三步实现SVIP免费加速终极指南
  • qcoder-chat-是什么以及能做什么
  • 东莞弘创激光科技:靠谱的东莞光纤非标机哪个公司好 - LYL仔仔
  • 2026汽车称重仪推荐排名,浙江润鑫,头部品牌实力护航 - 品牌速递
  • 2026年靠谱中石油加油卡回收平台精选 - 京顺回收
  • 2026主流Qi2认证磁吸充电宝实测 双认证合规选购全指南 - 速递信息
  • 庖丁解牛 YOLOv7:从骨干网络到检测头的模块化拆解
  • Adobe Illustrator脚本自动化:释放设计师生产力的28个专业工具全解析
  • 开源语义层Synmetrix部署与实战:统一指标定义,告别数据孤岛
  • 【强化学习】PPO算法调参实战:从理论到代码优化倒立摆控制