【NOI2016】區間 線段樹

題意

求有公共點的m個區間的最長區間的長度與最短區間長度的最小值。

題解

先將區間以長度爲關鍵字從小到大進行排序,易得最小值應該是排序後儘可能相近的兩個區間。用頭尾兩個指針控制,每次更新利用線段樹進行區間覆蓋來判斷是否符合有公共點的條件。

代碼

//bzoj4653[Noi2016]區間
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cctype>
#define ll long long
#define lson l,mid,pos<<1
#define rson mid+1,r,pos<<1|1
#define N 500100
#define inf 0x7fffffffffffffff
using namespace std;
struct Tree{int lazy,mx,d;}tree[N<<4];
struct node{ll x,y,len;}a[N];
int n,m,ToT;ll b[N<<1],ans=inf;
bool cmp(node p,node q){return p.len<q.len;}
int find(int x,int l,int r)
{
	if (l==r) return l;
	int mid=(l+r)>>1;
	if (x<=b[mid]) return find(x,l,mid);
	else return find(x,mid+1,r);
}
void pushup(int x){tree[x].mx=max(tree[x<<1].mx,tree[x<<1|1].mx);}
void pushdown(int x)
{
	int cur=tree[x].lazy;
	tree[x<<1].mx+=cur;tree[x<<1].lazy+=cur;
	tree[x<<1|1].mx+=cur;tree[x<<1|1].lazy+=cur;
	tree[x].lazy=0;
}
void build(int l,int r,int pos)
{
	if (l==r) {tree[pos].mx=0;return;}
	int mid=(l+r)>>1;
	build(lson);build(rson);
	pushup(pos);
}
void update(int L,int R,int x,int l,int r,int pos)
{
	if (L<=l&&r<=R) {tree[pos].mx+=x;tree[pos].lazy+=x;return;}
	int mid=(l+r)>>1;
	pushdown(pos);
	if (L<=mid) update(L,R,x,lson);
	if (R>mid) update(L,R,x,rson);
	pushup(pos);
}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a[i].x,&a[i].y);
		b[++ToT]=a[i].x;b[++ToT]=a[i].y;
		a[i].len=a[i].y-a[i].x+1;
	}
	sort(a+1,a+n+1,cmp);sort(b+1,b+ToT+1);
	for (int i=1;i<=n;i++) a[i].x=find(a[i].x,1,ToT),a[i].y=find(a[i].y,1,ToT);
	//for (int i=1;i<=ToT;i++) printf("%d ",b[i]);printf("\n");
	//for (int i=1;i<=n;i++) printf("%d %d %d\n",a[i].x,a[i].y,a[i].len);
	build(1,ToT,1);
	for (int i=1,j=0;i<=n;i++)
	{
		while(tree[1].mx<m)
		{
			if (j==n) break;
			j++;
			update(a[j].x,a[j].y,1,1,ToT,1);
		}
		if (tree[1].mx>=m) ans=min(ans,a[j].len-a[i].len);
		else break;
		update(a[i].x,a[i].y,-1,1,ToT,1);
	}
	if (ans==inf) printf("-1\n");
	else printf("%lld\n",ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章