由于现在做题比较杂,所以就不标号码了
感觉应该算是思维题?
刚开始没想到完全用线段树后来看了题解
如果想到线段树的话这题剩下的东西就可以很自然的想到了
贪心的把区间按区间长度排序
然后用尺取法
看看数据范围会发现需要离散化
好像也不是很好想
至少不算难打
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
struct node{
int l;
int r;
int mx;
int lan;
}s[2000005*4];
struct node2{
int l;
int r;
int val;
}a[5000005];
int n,m;
int ll[5000005],rr[500005];
#define ls q*2
#define rs q*2+1
bool cmp(node2 x,node2 y)
{
return x.val<y.val;
}
void build(int q,int l,int r)
{
s[q].l=l;
s[q].r=r;
if(l==r)
{
s[q].mx=0;
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
return ;
}
void chuan(int q)
{
if(s[q].lan)
{
s[ls].lan+=s[q].lan;
s[ls].mx+=s[q].lan;
s[rs].lan+=s[q].lan;
s[rs].mx+=s[q].lan;
s[q].lan=0;
}
return ;
}
void xg(int q,int l,int r,int k)
{
if(s[q].l>=l&&s[q].r<=r)
{
s[q].mx+=k;
s[q].lan+=k;
return ;
}
chuan(q);
int mid=(s[q].l+s[q].r)>>1;
if(l<=mid) xg(ls,l,r,k);
if(r>mid) xg(rs,l,r,k);
s[q].mx=max(s[ls].mx,s[rs].mx);
}
int main()
{
scanf("%d%d",&n,&m);
for1(i,1,n)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].val=a[i].r-a[i].l;
ll[i]=a[i].l;
ll[i+n]=a[i].r;
}
sort(ll+1,ll+2*n+1);
int ji=unique(ll+1,ll+2*n+1)-ll-1;
for1(i,1,n)
a[i].l=(lower_bound(ll+1,ll+ji+1,a[i].l)-ll);
for1(i,1,n)
a[i].r=(lower_bound(ll+1,ll+ji+1,a[i].r)-ll);
build(1,1,ji);
sort(a+1,a+n+1,cmp);
int jl=1;
int jr=0;
int ans=1e9;
while(jl<=n)
{
while(jr<n&&s[1].mx<m)
{
jr++;
xg(1,a[jr].l,a[jr].r,1);
}
if(jr==n &&s[1].mx<m) break;
ans=min(ans,a[jr].val-a[jl].val);
xg(1,a[jl].l,a[jl].r,-1);
jl++;
}
printf("%d\n",(ans==1e9)?-1:ans);
return 0;
}
标签:10,lan,17,rs,int,ll,P1712,for1,mx
From: https://www.cnblogs.com/yyx525jia/p/16806295.html