zoukankan      html  css  js  c++  java
  • 2017"百度之星"程序设计大赛

    给出n<=100000个已覆盖的区间[Li,Ri],Li,Ri<=1e9,求再覆盖m<=1e9个点如何使最长覆盖区间最大。

    感谢KPM大爷的题解!!

    首先把重复区间处理掉,剩下若干个不重区间。这采用类似于差分的“事件法”,左边+1,右边-1,>0的部分即是区间。

    接下来,“求满足某个条件的最长区间”,twopointer!

    注意<和<=的运用!代码中用的是左右闭区间,但实操发现处理成左闭右开区间更方便。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 #include<math.h>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,m;
    10 #define maxn 100011
    11 struct Line
    12 {
    13     int v,id;
    14     bool operator < (const Line &b) const
    15     {return id<b.id || (id==b.id && v<b.v);}
    16 }l[maxn];int len;
    17 struct Point
    18 {
    19     int l,r;
    20 }nl[maxn];int ln;
    21 int x,y;
    22 #define LL long long
    23 int main()
    24 {
    25     while (~scanf("%d%d",&n,&m))
    26     {
    27         len=0;
    28         for (int i=1;i<=n;i++)
    29         {
    30             scanf("%d%d",&x,&y);
    31             l[++len].v=1;l[len].id=x;
    32             l[++len].v=-1;l[len].id=y+1;
    33         }
    34         sort(l+1,l+1+len);
    35         int now=0,L,R;ln=0;
    36         for (int i=1;i<=len;i++)
    37         {
    38             now+=l[i].v;
    39             if (now==1 && l[i].v==1) L=l[i].id;
    40             else if (now==0) 
    41             {
    42                 R=l[i].id-1;
    43                 nl[++ln].l=L;nl[ln].r=R;
    44             }
    45         }
    46         now=0,L=1,R=1;
    47         LL ans=0;
    48         nl[0].l=nl[0].r=0;
    49         while (L<=ln && R<=ln)
    50         {
    51             while (R<=ln && now<=m)
    52             {
    53                 ans=max(ans,(LL)((nl[R].r-nl[L].l+1)+m-now));
    54                 R++;
    55                 if (R<=ln) now+=nl[R].l-nl[R-1].r-1;
    56             }
    57             L++;
    58             now-=nl[L].l-nl[L-1].r-1;
    59         }
    60         while (L<ln && now>m)
    61         {
    62             L++;
    63             now-=nl[L].l-nl[L-1].r-1;
    64         }
    65         if (L<=ln) ans=max(ans,(LL)(nl[ln].r-nl[L].l+1)+m-now);
    66         printf("%lld
    ",ans);
    67     }
    68     return 0;
    69 }
    View Code

    前面处理区间的部分可以优化,只要把区间按左端点排序,相同时右端点靠右的在前,然后时时记录枚举到的最右端点即可。---TJM。

  • 相关阅读:
    判断DataReader中是否有指定列
    datatable dateset 载体传递数据、存储过程
    抓取网页信息
    捕获异常 winform
    修改myeclipse的jsp模板
    包装设计模式的实现以改进BufferedReader中的readLine方法为例
    查询图书馆借书情况-代码
    查询四六级成绩
    Sqlyog增加试用期
    MVC笔记-模板页布局
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7354477.html
Copyright © 2011-2022 走看看