• CF 1249D1


    https://codeforces.com/blog/entry/70779

    分析:想到在要删去一条线段时贪心的选取右坐标最长的那一个肯定正确。

    就可以利用排序,即set的自动排序再重定义运算符来处理(按左坐标的顺序插入,按右坐标大小排序),用size()表示覆盖的边数,坐标从左到右一个个该删删该增增,维护一遍。

    一个技巧:vector<Node> segs[maxn]  的Node 是右坐标 和 线段的序号,而用数组下标用左坐标来表示,就能够实现上述的坐标上扫一遍的处理。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 2e5+10;
    
    struct Node{
        int r;
        int idx;
    };
    bool operator < (Node a,Node b){
            if(a.r != b.r)
                return a.r<b.r;
            return a.idx<b.idx;
    }
    
    vector<Node> segs[maxn];
    set<int> ans;
    int n,k,x,y;
    
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>k;
        for(int i=0; i<n; i++){
            cin>>x>>y;
            Node temp;
            temp.r = y;
            temp.idx = i;
            segs[x].push_back(temp);
        }
        set<Node> s;
        for(int i=0; i<maxn; i++){
            while(s.size() && (*s.begin()).r<i ){
                s.erase(s.begin());
            }
            for(Node it: segs[i]){
                s.insert(it);
            }
            while(s.size() > k){
                ans.insert( (*s.rbegin()).idx );
                s.erase( *(s.rbegin()) );
            }
        }
        cout<<ans.size()<<endl;
        for(int it : ans){
            cout<<it+1<<" ";
        }
        cout<<endl; 
    }
    
    
    //c.begin() 返回一个迭代器,它指向容器c的第一个元素
    
    // c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置
    
    // c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素
    
    // c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素前面的位置
  • 相关阅读:
    win 10 安装 Chocolatey
    css文字禁止选中
    解决手机端上的iframe无法触摸滚动
    关于a标签
    移动端点击a标签和img标签以及添加的js点击事件时的闪屏问题 解决方案
    关于时间戳
    json转字符串
    css一行溢出隐藏,两行溢出隐藏
    centos 7.x编写开机启动服务
    编译LFS
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11787495.html
Copyright © 2020-2023  润新知