zoukankan      html  css  js  c++  java
  • [NOI2016]区间

    题目描述

    在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn]。现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri。

    对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值。

    求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。

    输入输出格式

    输入格式:

    第一行包含两个正整数 n,m用空格隔开,意义如上文所述。保证 1≤m≤n

    接下来 n行,每行表示一个区间,包含用空格隔开的两个整数 li 和 ri 为该区间的左右端点。

    N<=500000,M<=200000,0≤li≤ri≤10^9

    输出格式:

    只有一行,包含一个正整数,即最小花费。

    输入输出样例

    输入样例#1: 复制
    6 3
    3 5
    1 2
    3 4
    2 2
    1 5
    1 4
    输出样例#1: 复制
    2

    题解:

    好久以前做的一道题,补一下博客。

    因为题目要求的是min(最大区间长度-最小区间长度),所以考虑按照区间长度排序。

    尺取法,用线段树维护区间最大值,每次将相同长度的区间加入线段树,然后始终保持当前状态下有点被覆盖了m次。

    在保持这个前提条件的情况下,尽量的出队,尽量的少入队,实际上就是保证了最大区间长度-最小区间长度最小。

    坐标范围比较大,离散化一下就好。(这个离散化打得很丑)

     1 //Never forget why you start
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<algorithm>
     8 #define ll(x) (x<<1)
     9 #define rr(x) (x<<1|1)
    10 using namespace std;
    11 int n,m;
    12 struct node{
    13   int l,r,len,ll,rr;
    14 }a[500005];
    15 bool cmp(const node a,const node b){
    16   return a.len<b.len;
    17 }
    18 int sgm[4000005],lazy[4000005];
    19 void push_up(int root,int left,int right){
    20   sgm[root]=max(sgm[ll(root)],sgm[rr(root)]);
    21 }
    22 void build(int root,int left,int right){
    23   if(left==right){
    24     sgm[root]=0;
    25     return;
    26   }
    27   if(left>right)return;
    28   int mid=(left+right)>>1;
    29   build(ll(root),left,mid);
    30   build(rr(root),mid+1,right);
    31   push_up(root,left,right);
    32 }
    33 void push_down(int root,int left,int right){
    34   int mid=(left+right)>>1;
    35   sgm[ll(root)]+=lazy[root];
    36   sgm[rr(root)]+=lazy[root];
    37   lazy[ll(root)]+=lazy[root];
    38   lazy[rr(root)]+=lazy[root];
    39   lazy[root]=0;
    40 }
    41 void insert(int root,int left,int right,int l,int r,int v){
    42   if(l<=left&&right<=r){
    43     sgm[root]+=v;
    44     lazy[root]+=v;
    45     return;
    46   }
    47   if(l>right||r<left)return;
    48   push_down(root,left,right);
    49   int mid=(left+right)>>1;
    50   if(l<=mid)insert(ll(root),left,mid,l,r,v);
    51   if(mid<r)insert(rr(root),mid+1,right,l,r,v);
    52   push_up(root,left,right);
    53 }
    54 struct point{
    55   int x,id,y;
    56 }b[1000005];
    57 bool cmp2(const point a,const point b){
    58   return a.x<b.x;
    59 }
    60 bool cmp3(const point a,const point b){
    61   return a.id<b.id;
    62 }
    63 int q[500005],ans=2000000000;
    64 int main(){
    65   int i,j;
    66   scanf("%d%d",&n,&m);
    67   for(i=1;i<=n;i++){
    68     scanf("%d%d",&a[i].l,&a[i].r);
    69     a[i].ll=a[i].l;a[i].rr=a[i].r;
    70   }
    71   for(i=1;i<=n;i++){
    72     b[ll(i)].x=a[i].l;b[ll(i)].id=ll(i);
    73     b[rr(i)].x=a[i].r;b[rr(i)].id=rr(i);
    74   }
    75   sort(b+2,b+(n<<1|1)+1,cmp2);
    76   int end=(n<<1|1),cnt=0;
    77   b[1].x=-1;
    78   for(i=2;i<=end;i++){
    79     if(b[i].x!=b[i-1].x)cnt++;
    80     b[i].y=cnt;
    81   }
    82   sort(b+2,b+(n<<1|1)+1,cmp3);
    83   for(i=1;i<=n;i++){
    84     a[i].l=b[ll(i)].y;
    85     a[i].r=b[rr(i)].y;
    86     a[i].len=a[i].rr-a[i].ll;
    87   }
    88   sort(a+1,a+n+1,cmp);
    89   build(1,1,cnt);
    90   int l=1,r=0;
    91   while(1){
    92     while(sgm[1]<m&&r+1<=n)r++,insert(1,1,cnt,a[r].l,a[r].r,1);
    93     while(sgm[1]>=m&&l<=r)ans=min(ans,a[r].len-a[l].len),insert(1,1,cnt,a[l].l,a[l].r,-1),l++;
    94     if(r==n)break;
    95   }
    96   if(ans!=2000000000)printf("%d
    ",ans);
    97   else printf("-1
    ");
    98   return 0;
    99 }
  • 相关阅读:
    Attach Files to Objects 将文件附加到对象
    Provide Several View Variants for End-Users 为最终用户提供多个视图变体
    Audit Object Changes 审核对象更改
    Toggle the WinForms Ribbon Interface 切换 WinForms 功能区界面
    Change Style of Navigation Items 更改导航项的样式
    Apply Grouping to List View Data 将分组应用于列表视图数据
    Choose the WinForms UI Type 选择 WinForms UI 类型
    Filter List Views 筛选器列表视图
    Make a List View Editable 使列表视图可编辑
    Add a Preview to a List View将预览添加到列表视图
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/8284210.html
Copyright © 2011-2022 走看看