UOJ 222
http://uoj.ac/problem/222
对区间离散化
然后区间长度排序+双指针支取+标记永久化的线段树维护
#include<cstdio> #include<algorithm> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using namespace std; const int N=1000011,inf=2147483647; int ans,n,m; struct qs{ int l,r; inline bool operator<(qs A)const{return (r-l)<(A.r-A.l);} }q[N]; int b[N<<1]; int tr[N<<2],ad[N<<2]; inline int max(int a,int b){return a>b?a:b;} inline int min(int a,int b){return a<b?a:b;} inline int d(int x,int y){return ((b[q[x].r]-b[q[x].l])-(b[q[y].r]-b[q[y].l]));} inline void change(int k,int l,int r,int x,int y,int z){ if(x<=l&&r<=y){ tr[k]+=z,ad[k]+=z; return ; } int mid=(l+r)>>1; if(x<=mid)change(k<<1,l,mid,x,y,z); if(mid<y)change(k<<1|1,mid+1,r,x,y,z); tr[k]=max(tr[k<<1],tr[k<<1|1])+ad[k]; } int main(){ ans=inf; scanf("%d%d",&n,&m); FOR(i,1,n)scanf("%d%d",&q[i].l,&q[i].r),b[++b[0]]=q[i].l,b[++b[0]]=q[i].r; sort(b+1,b+b[0]+1);sort(q+1,q+n+1); b[0]=unique(b+1,b+b[0]+1)-b-1; FOR(i,1,n) q[i].l=lower_bound(b+1,b+b[0]+1,q[i].l)-b, q[i].r=lower_bound(b+1,b+b[0]+1,q[i].r)-b; for(register int l=1,r=1;l<=n;++l){ while(r<=n&&tr[1]<m)change(1,1,b[0],q[r].l,q[r].r,1),++r; if(r>n&&tr[1]<m)break; ans=min(ans,d(r-1,l)); change(1,1,b[0],q[l].l,q[l].r,-1); } printf("%d",ans==inf?-1:ans); return 0; }