$n leq 500000$个区间,从中挑出一些,使得至少有一个点被$m$个选中区间包含,且选中区间长度的极差最小。
区间题死脑筋晚期:把区间按左端点排序,然后右端点用个优先队列来弹,然后需要维护下标相差$m$的数字差的最值,可以在$n^2$的时间完美拿到签到题的60分。
求极差嘛,就是关注最大最小,不如把区间按长度升序,这样枚举两个区间时,可以把大小在他们之间的都加进线段树观察是否合法。然鹅,可以发现较长区间R往后枚举越来越长后,最优的较短区间L不会变小,也就是满足决策单调性,可以双指针搞定。
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 14 int qread() 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);} 39 void addsingle(int x,int v) {a[x].add+=v; a[x].Max+=v;} 40 void down(int x) {if (a[x].add) {addsingle(a[x].ls,a[x].add); addsingle(a[x].rs,a[x].add); a[x].add=0;} } 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; 47 if (ql<=mid) Add(a[x].ls,L,mid); 48 if (qr>mid) Add(a[x].rs,mid+1,R); 49 up(x); 50 } 51 void add(int x,int y,int V) {ql=x; qr=y; v=V; Add(1,1,n);} 52 }t; 53 54 int main() 55 { 56 n=qread(); m=qread(); 57 for (int i=1;i<=n;i++) 58 {p[i].x=qread(); p[i].y=qread()+1; p[i].v=p[i].y-p[i].x-1; lisa[++li]=p[i].x; lisa[++li]=p[i].y;} 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 { 68 t.add(p[i].x,p[i].y-1,1); 69 for (;j<=n;j++) 70 { 71 t.add(p[j].x,p[j].y-1,-1); 72 if (t.a[1].Max<m) {t.add(p[j].x,p[j].y-1,1); break;} 73 } 74 if (t.a[1].Max>=m) ans=min(ans,p[i].v-p[j].v); 75 } 76 printf("%d ",ans==0x3f3f3f3f?-1:ans); 77 return 0; 78 }