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;
    }
posted @   Bellala  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示