cf612 D. The Union of k-Segments(被至少K条线段覆盖的所有区间)
题意:
给定n条线段,如果一个实数点被至少K条线段覆盖,称为好点。输出一列总长度最小的、包含所有好点的闭区间
输入均为整数
思路:
传世经典题。
差分思想:想象一个实数轴,所有线段左端点坐标处打上1标记,右端点打上-1。对所涉所有坐标排序,计算前缀和 k。根据当前的 k 可以判断当前点被覆盖的情况
int n, K; vector<PII> ve; //位置,类型
vector<PII> ans; //答案
signed main() {
iofast;
cin >> n >> K;
for(int i = 1; i <= n; i++) {
int l, r; cin >> l >> r;
ve.pb({l, 1}), ve.pb({r, -1});
}
sort(all(ve), [](PII &x, PII &y) { //保证先加再减
return x.fi != y.fi ? x.fi < y.fi : x.se > y.se;
});
int k = 0; for(auto &[p,t] : ve) {
if(k == K - 1 && t == 1) ans.pb({p,0});
if(k == K && t == -1) ans.back().se = p;
k += t;
}
cout << ans.size() << endl;
for(auto &[l,r] : ans) cout << l << ' ' << r << endl;
}
细节可以稍有不同:
for(int i = 1; i <= n; i++) {
int l, r; cin >> l >> r;
ve.pb({l, 1}), ve.pb({r + 1, -1}); //这样
}
sort(all(ve)); //这样
int k = 0; for(auto &[p,t] : ve) {
if(k == K - 1 && t == 1) ans.pb({p,0});
if(k == K && t == -1) ans.back().se = p-1;//这样
k += t;
}
标签:
前缀和与差分
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通