zoukankan      html  css  js  c++  java
  • CodeForces1249D2Too Many Segments (hard version) STL+贪心

    The only difference between easy and hard versions is constraints.

    You are given nn segments on the coordinate axis OXOX. Segments can intersect, lie inside each other and even coincide. The ii-th segment is [li;ri][li;ri] (lirili≤ri) and it covers all integer points jj such that lijrili≤j≤ri.

    The integer point is called bad if it is covered by strictly more than kk segments.

    Your task is to remove the minimum number of segments so that there are no bad points at all.

    Input

    The first line of the input contains two integers nn and kk (1kn21051≤k≤n≤2⋅105) — the number of segments and the maximum number of segments by which each integer point can be covered.

    The next nn lines contain segments. The ii-th line contains two integers lili and riri (1liri21051≤li≤ri≤2⋅105) — the endpoints of the ii-th segment.

    Output

    In the first line print one integer mm (0mn0≤m≤n) — the minimum number of segments you need to remove so that there are no bad points.

    In the second line print mdistinct integers p1,p2,,pmp1,p2,…,pm (1pin1≤pi≤n) — indices of segments you remove in any order. If there are multiple answers, you can print any of them.

    Examples

    Input
    7 2
    11 11
    9 11
    7 8
    8 9
    7 8
    9 11
    7 9
    
    Output
    3
    4 6 7 
    
    Input
    5 1
    29 30
    30 30
    29 29
    28 30
    30 30
    
    Output
    3
    1 4 5 
    
    Input
    6 1
    2 3
    3 3
    2 3
    2 2
    2 3
    2 3
    
    Output
    4
    1 3 5 6 


    题意:
    给定n个线段的覆盖区间
    求最少删除多少个线段可以让覆盖每个点的线段数量<=k

    思路:
    从前往后找如果大于k
    就删掉该点所有线段上 右端点最靠右 的线段

    vector<int>v;//相当于数组的作用了

    学习到了这个新的用法和容器:

    set<pair<int,int> >s;//两个> >中间要加空格隔开
    因为set会自动升序排列
    把里面每一个元素都看作是pair
    则排序是先排pair里的first,再排pair里面的second
    比如pair<2,3> pair<2,1> pair<0,6>
    排列之后是pair<0,6>,pair<2,1>,pair<2,3>

    pair<int,int> 

    这是泛型
    pair是一个键值对
    键是int类型,值是int类型
    然后这种类型的变量组成一个set,也就是集合
    这个集合的变量叫s

    codeforces上好像是不太注意格式的。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=2e5+20;
     4 #define inf 0x3f3f3f3f
     5 
     6 struct node
     7 {
     8     int l;
     9     int r;
    10     int num;
    11 } a[N];
    12 
    13 int cmp1(node a,node b)
    14 {
    15 //    if(a.r!=b.r)
    16 //        return a.r>b.r;
    17 //    else
    18         return a.l<b.l;//按左端点从小到大排序
    19 }
    20 //题意:
    21 //给定n个线段的覆盖区间
    22 //求最少删除多少个线段可以让覆盖每个点的线段数量<=k
    23 
    24 //思路:
    25 //从前往后找如果大于k
    26 //就删掉该点所有线段上 右端点最靠右 的线段
    27 
    28 vector<int>v;//相当于数组的作用了
    29 
    30 set<pair<int,int> >s;//两个> >中间要加空格隔开
    31 //因为set会自动升序排列
    32 //把里面每一个元素都看作是pair
    33 //则排序是先排pair里的first,再排pair里面的second
    34 //比如pair<2,3> pair<2,1> pair<0,6>
    35 //排列之后是pair<0,6>,pair<2,1>,pair<2,3>
    36 
    37 //这是泛型
    38 //pair是一个键值对
    39 //键是int类型,值是int类型
    40 //然后这种类型的变量组成一个set,也就是集合
    41 //这个集合的变量叫s
    42 
    43 //7 2
    44 //11 11
    45 //9 11
    46 //7 8
    47 //8 9
    48 //7 8
    49 //9 11
    50 //7 9
    51 
    52 //3
    53 //4 6 7
    54 pair<int,int>p;
    55 
    56 int main()
    57 {
    58     int n,k;
    59     while(~scanf("%d %d",&n,&k))
    60     {
    61         v.clear();
    62         s.clear();
    63         //p.clear();//不可以
    64         int maxx=-1,minn=inf;
    65         for(int i=1; i<=n; i++)
    66         {
    67             scanf("%d %d",&a[i].l,&a[i].r);
    68             a[i].num=i;
    69             maxx=max(maxx,a[i].r);//找到最大的右端点
    70             minn=min(minn,a[i].l);//找到最小的左端点
    71         }
    72         sort(a+1,a+1+n,cmp1);////按左端点从小到大排序
    73         int q=1;
    74         for(int i=minn; i<=maxx; i++)
    75         {
    76             while(q<=n&&a[q].l<=i)
    77             {
    78                 s.insert(make_pair(a[q].r,a[q].num));
    79                 q++;
    80             }
    81             while(s.size()&&s.begin()->first<i)
    82                 s.erase(s.begin()); //默认排序从小到大
    83             while(s.size()>k)//s里面存的是每一个点被线段覆盖的次数
    84             {
    85                 p=*(--s.end());
    86                 v.push_back(p.second);
    87                 s.erase(p);
    88             }
    89         }
    90         sort(v.begin(),v.end());
    91         cout<<v.size()<<endl;
    92         for(int i=0; i<v.size(); i++)
    93             cout<<v[i]<<' ';
    94 //        cout<<v[v.size()-1]<<endl;//RT 不知道为啥???
    95         cout<<endl;
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    面向对象的本质是算法的上下文封装,是同一类属的行为接口的一致性
    结构化方法和面向对象方法的比较
    需求文档和软件都是服务的集合
    注意 Laravel 清除缓存 php artisan cache:clear 的一个坑
    面向对象复习笔记(一)
    详解如何在Laravel中增加自定义全局函数
    Laravel 引入自定义类库或第三方类库
    PHP怎么调用其他类的方法
    Laravel如何引用第三方(自定义)库
    laravel框架手机发送验证码
  • 原文地址:https://www.cnblogs.com/OFSHK/p/11788299.html
Copyright © 2011-2022 走看看