zoukankan      html  css  js  c++  java
  • cf 1249 D2. Too Many Segments (hard version) (贪心+multiset)

    题意:

    有n条线段,每条线段覆盖的点为[li,ri],如果点被超过k条线段覆盖,那么这个点为坏点,

    问,最少去掉哪几条线段,可以使得没有坏点?

    思路:

    点从左往右扫,如果这个点为坏点,那么就去掉一些 覆盖这个点的线段,从ri最大的开始删,不需要考虑li是因为你已经保证左边没有坏点了,那么删掉的线段当然是ri越大越好。

    用multiset维护当前覆盖这个点的线段是哪几条。

    今天才知道,sort的时候,外部定义的cmp函数可以覆盖结构体里的重载运算符'<'。

    果然不是大佬就少用stl,测样例的时候RE,交了两发也RE,调好久。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <cmath>
    #include <iostream>
    #include <vector>
    #include <set>
    #include <algorithm>
    using namespace std;
    typedef long long int ll;
    const double pi = acos(-1);
    const int maxn = 2e5 + 10;
    const int inf = 0x3f3f3f3f;
    struct node
    {
        int l,r,id;
        friend bool operator <(node x,node y){
            return x.r < y.r;
        }
    }a[maxn];
    
    bool cmp(node x,node y)
    {
        return x.l < y.l;
    }
    int vis[maxn];
    multiset<node>st;
    int main()
    {
        multiset<node>::iterator it;
        int n,k,ans,mx;
        while(scanf("%d%d",&n,&k) != EOF){
            ans = 0;
            mx = 0;
            st.clear();
            memset(vis,0,sizeof(vis));
            for(int i = 1;i <= n;i++){
                scanf("%d%d",&a[i].l,&a[i].r);
                mx = max(mx,a[i].r);
                a[i].id = i;
            }
            sort(a + 1,a + n + 1,cmp);
            int cnt = 1,now = 0;
            for(int i = 1;i <= mx;i++){
                it = st.begin();
                while(it != st.end() && (*it).r < i){
                    st.erase(it);
                    it = st.begin();
                    now--;
                }
                while(cnt <= n && a[cnt].l <= i){
                    st.insert(a[cnt]);
                    cnt++;
                    now++;
                }
                it = st.end();
                while(now > k){
                    it--;
                    vis[(*it).id] = 1;
                    st.erase(it);
                    
                    it = st.end();
                    now--;
                    ans++;
                }
            }
            printf("%d
    ",ans);
            for(int i = 1;i <= n;i++){
                if(vis[i])
                    printf("%d ",i);
            }
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    workerPool _ golang
    jsp:JDBCmysql数据库连接
    jsp:session的跟踪方式
    js:使用nodejs为页面传递mysql中的数据
    js:网页中的高和宽(document)
    js:nodejs简单的Http服务器搭建
    js:面向对象编程
    js:nextSibling兄弟节点的使用
    java:mysql基础语法
    jsp:常用标签的核心标签的使用
  • 原文地址:https://www.cnblogs.com/InitRain/p/12445914.html
Copyright © 2011-2022 走看看