标签:
题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度。现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW。后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报。现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到。)
思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用hh牛的话:
而这题的难点在于每个数字其实表示的是一个单位长度(并非一个点),这样普通的离散化会造成许多错误(包括我以前的代码,poj这题数据奇弱)
给出下面两个简单的例子应该能体现普通离散化的缺陷:
例子一:1-10 1-4 5-10
例子二:1-10 1-4 6-10
普通离散化后都变成了[1,4][1,2][3,4]
线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?
例子一是完全被覆盖掉了,而例子二没有被覆盖
//1412 KB 79 ms #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define M 10005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; int col[M*16]; int poi[M*4]; //因为经过了特殊化处理,所以在2*M的基础上又放大了一倍 int li[M],ri[M]; bool book[M]; void build(int l,int r,int rt) { col[rt]=-1; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } int Bin(int g,int m) //二分出离散后的序号 { int l=0,r=m-1; while(r>=l){ int mid=(l+r)>>1; if(poi[mid]==g) return mid; else if(poi[mid]>g) r=mid-1; else l=mid+1; } } void pushdown(int rt) { if(col[rt]==-1) return ; col[rt<<1]=col[rt<<1|1]=col[rt]; col[rt]=-1; } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R){ col[rt]=c; return; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); } int query(int l,int r,int rt) { int ans=0; if(col[rt]!=-1){ if(!book[col[rt]]){ book[col[rt] ]=true; ans++; } return ans; } if (l == r) return 0; int m=(l+r)>>1; ans+=query(lson); ans+=query(rson); return ans; } int main() { int cas,n; scanf("%d",&cas); while(cas--){ scanf("%d",&n); int cnt=0; for(int i=1;i<=n;i++){ scanf("%d%d",&li[i],&ri[i]); poi[cnt++]=li[i]; poi[cnt++]=ri[i]; } sort(poi,poi+cnt); int top=1; for(int i=1;i<cnt;i++){ if(poi[i]!=poi[i-1]){ //去重 poi[top++]=poi[i]; } } int tmp=top; for(int i=1;i<tmp;i++){ //特殊化处理 if(poi[i]-poi[i-1]>1){ poi[top++]=poi[i-1]+1; } } sort(poi,poi+top); build(0,top-1,1); int c=0; //待标记的颜色 for(int i=1;i<=n;i++){ int l=Bin(li[i],top); int r=Bin(ri[i],top); update(l,r,++c,0,top-1,1); } memset(book,0,sizeof(book)); printf("%d\n",query(0,top-1,1)); } return 0; }
POJ 2528 Mayor's posters (hash+线段树成段更新)
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/43882899