题目描述
现给定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; }