#1079 : 离散化
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~
这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住。看到这个场景,小Hi便产生了这样的一个疑问——最后到底能有几张海报还能被看见呢?
于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作长度为L的一段区间,且有N张海报按照顺序依次贴在了宣传栏上,其中第i张海报贴住的范围可以用一段区间[a_i, b_i]表示,其中a_i, b_i均为属于[0, L]的整数,而一张海报能被看到当且仅当存在长度大于0的一部分没有被后来贴的海报所遮挡住。那么问题就来了:究竟有几张海报能被看到呢?
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第1行为两个整数N和L,分别表示总共贴上的海报数量和宣传栏的宽度。
每组测试数据的第2-N+1行,按照贴上去的先后顺序,每行描述一张海报,其中第i+1行为两个整数a_i, b_i,表示第i张海报所贴的区间为[a_i, b_i]。
对于100%的数据,满足N<=10^5,L<=10^9,0<=a_i<b_i<=L。
输出
对于每组测试数据,输出一个整数Ans,表示总共有多少张海报能被看到。
- 样例输入
-
5 10 4 10 0 2 1 6 5 9 3 4
- 样例输出
-
5
题目链接:http://hihocoder.com/problemset/problem/1079
题意:n张海报按顺序粘贴,每张海报粘贴的位置为[ai,bi],问最后在墙上[0,L]能看到多少张海报。
思路:因为n只有105,而粘贴区间却有109。首先离散化海报的张贴区间。然后利用线段树区间更新来更新粘贴区间。注意:
由于海报的粘贴区间是非离散化的数据,即是连续的。所以[l,r]必须分解成[l,mid][mid,r]。这是与离散型数据的区别,
离散型数据的区间[l,r]分解成[l,mid][mid+1,r]。
例如这样一种数据:
3 4
1 4
1 2
3 4
如果按照离散型数据来二分区间的话,最后只能是有2张海报。1,2是一张,3,4是第二张,并没有考虑2~3的情况。
按照连续性的数据来二分的花,就可以是1~2,2~3,3~4。
其实按照离散型数据来二分区间也是可以的,只需要把[ai,bi]变成[ai*2,bi*2]就可以了。
TL中unique的函数 unique的功能是去除相邻的重复元素(只保留一个),不是真正把重复的元素删除,其实是,该函数把重复的元素一到后面去了,然后依然保存到了原数组中,然后返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。
代码:#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1e6+100; int l[MAXN],r[MAXN],c[2*MAXN]; int lazy[MAXN]; int date[MAXN]; int compress(int n) { memcpy(c,l,sizeof(l)); memcpy(c+n,r,sizeof(r)); sort(c,c+2*n); int size=unique(c,c+2*n)-c; for(int i=0; i<n; i++) { l[i]=lower_bound(c,c+size,l[i])-c+1; r[i]=lower_bound(c,c+size,r[i])-c+1; l[i]*=2; r[i]*=2; } return size; } void pushdown(int l,int r,int pos) { if(lazy[pos]==0) return; int mid=(l+r)<<1; lazy[pos<<1]=lazy[pos]; lazy[pos<<1|1]=lazy[pos]; lazy[pos]=0; } void update(int L,int R,int i,int l,int r,int pos) { if(L<=l&&r<=R) { lazy[pos]=i; return; } pushdown(l,r,pos); int mid=(l+r)>>1; if(L<=mid) update(L,R,i,l,mid,pos<<1); if(R>mid) update(L,R,i,mid+1,r,pos<<1|1); } void query(int l,int r,int pos) { if(l==r) { date[l]=lazy[pos]; return; } pushdown(l,r,pos); int mid=(l+r)>>1; query(l,mid,pos<<1); query(mid+1,r,pos<<1|1); } int main() { int i,n,L; while(~scanf("%d%d",&n,&L)) { memset(lazy,0,sizeof(lazy)); memset(c,0,sizeof(lazy)); for(i=0; i<n; i++) scanf("%d%d",&l[i],&r[i]); L=compress(n)*2; for(i=0; i<n; i++) { if(l[i]==r[i]) continue; update(l[i],r[i],i+1,1,L,1); } query(1,L,1); sort(date,date+2*L+1); int ans=unique(date,date+2*L+1)-(date+1); cout<<ans<<endl; } return 0; }