题目描述
现给定n个闭区间[ai, bi],1<=i<=n。这些区间的并可以表示为一些不相交的闭区间的并。你的任务就是在这些表示方式中找出包含最少区间的方案。你的输出应该按照区间的升序排列。这里如果说两个区间[a, b]和[c, d]是按照升序排列的,那么我们有a<=b<c<=d。
请写一个程序:
读入这些区间;
计算满足给定条件的不相交闭区间;
把这些区间按照升序输出。
输入输出格式
输入格式:第一行包含一个整数n,3<=n<=50000,为区间的数目。以下n行为对区间的描述,第i行为对第i个区间的描述,为两个整数1<=ai<bi<=1000000,表示一个区间[ai, bi]。
输出计算出来的不相交的区间。每一行都是对一个区间的描述,包括两个用空格分开的整数,为区间的上下界。你应该把区间按照升序排序。
题解:
其实这题有很多简单的方法可以解决,但我们为了练习线段树的能力,用线段树来实现它。我们把区间[u,v]变成[u*2,v*2],并每次对这个区间整体+1,这样可以保证两个区间的边界处不会被增加。然后枚举出现过的数,一个个统计答案即可。
AC代码:
#include<cstdio>
#include<iostream>
#define ll int
using namespace std;
const int Maxn=2000015;
ll a[Maxn];
struct node{
ll x,c;
int l,r;
}t[Maxn*8];
int m;
inline int lson(int x){
return x*2;
}
inline int rson(int x){
return x*2+1;
}
inline int pushup(int rt){
t[rt].x=t[lson(rt)].x+t[rson(rt)].x;
}
inline void build(int l,int r,int rt){
t[rt].l=l;t[rt].r=r;
if(l==r){
t[rt].x=a[l];
return;
}
int mid=l+r>>1;
build(l,mid,lson(rt));
build(mid+1,r,rson(rt));
pushup(rt);
}
inline int len(int rt){
return t[rt].r-t[rt].l+1;
}
inline void pushdown(int rt){
if(t[rt].l==t[rt].r)return;
if(t[rt].c==0)return;
t[lson(rt)].c+=t[rt].c;
t[rson(rt)].c+=t[rt].c;
t[lson(rt)].x+=t[rt].c*len(lson(rt));
t[rson(rt)].x+=t[rt].c*len(rson(rt));
t[rt].c=0;
}
inline void update(int l,int r,ll x,int rt){
if(t[rt].l>=l&&t[rt].r<=r){
t[rt].x+=x*len(rt);
t[rt].c+=x;
return;
}
pushdown(rt);
int mid=t[rt].l+t[rt].r>>1;
if(l<=mid){
update(l,r,x,lson(rt));
}
if(r>mid){
update(l,r,x,rson(rt));
}
pushup(rt);
}
inline ll query(int l,int rt){
if(t[rt].l==l&&t[rt].r==l){
return t[rt].x;
}
pushdown(rt);
int mid=t[rt].l+t[rt].r>>1;
if(l<=mid)return query(l,lson(rt));
else return query(l,rson(rt));
}
inline int mx(int x,int y){
return x>y?x:y;
}
int main(){
int u,v,inc,maxn,now=1;
bool flag=1;
scanf("%d",&m);
build(1,2000005,1);
while(m--){
scanf("%d%d",&u,&v);
update(u*2,v*2,1,1);
maxn=mx(maxn,v*2);
}
while(now<=maxn){
if(flag==0){
printf("%d ",now/2);
while(query(now,1)&&now<=maxn)now++;
printf("%d\n",now/2);
flag=1;
}
else{
while(!query(now,1)&&now<=maxn)now++;
flag=0;
}
}
return 0;
}