# LOJ#2086. 「NOI2016」区间

$n \leq 500000$个区间，从中挑出一些，使得至少有一个点被$m$个选中区间包含，且选中区间长度的极差最小。

 1 //#include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<bitset>
8 //#include<vector>
9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12
13 #define LL long long
15 {
16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
18 }
19
20 //Pay attention to '-' , LL and double of qread!!!!
21
22 int n,m;
23 #define maxn 500011
24 struct Line{int x,y,v; bool operator < (const Line &b) const {return v<b.v;} }p[maxn];
25
26 int lisa[maxn*2],li=0;
27 struct SMT
28 {
29     struct Node{int ls,rs,Max,add;}a[maxn<<2]; int size,n;
30     void up(int x) {a[x].Max=max(a[a[x].ls].Max,a[a[x].rs].Max);}
31     void build(int &x,int L,int R)
32     {
33         x=++size;
34         if (L==R) return;
35         int mid=(L+R)>>1;
36         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R);
37     }
38     void clear(int N) {n=N; size=0; int x; build(x,1,n);}
41     int ql,qr,v;
42     void Add(int x,int L,int R)
43     {
44         if (ql<=L && R<=qr) {addsingle(x,v); return;}
45         down(x);
46         int mid=(L+R)>>1;
49         up(x);
50     }
52 }t;
53
54 int main()
55 {
57     for (int i=1;i<=n;i++)
59     sort(p+1,p+1+n); sort(lisa+1,lisa+1+li); li=unique(lisa+1,lisa+1+li)-lisa-1;
60     for (int i=1;i<=n;i++) p[i].x=lower_bound(lisa+1,lisa+1+li,p[i].x)-lisa,
61     p[i].y=lower_bound(lisa+1,lisa+1+li,p[i].y)-lisa;
62
63     t.clear(li);
64
65     int ans=0x3f3f3f3f;
66     for (int i=1,j=1;i<=n;i++)
67     {
69         for (;j<=n;j++)
70         {
78 }