您的位置:首页 > 其它

poj2528 Mayor's posters 线段树,成段更新,离散化

2014-06-04 20:24 381 查看
题目链接:http://poj.org/problem?id=2528

大致题意:

有一面墙,被等分为1QW份,一份的宽度为一个单位宽度。现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW。后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报。现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到。)

这道题看了小优师姐的博客和HH大牛的博客,总算搞懂了。。。看懂后自己写了一遍代码,A掉

///2014.6.4
///poj2528

//1660K   94MS

/**
*离散化 + 线段树
*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1

#define maxn 12000

int segT[maxn<<4];   //线段树数组,叶子节点数最多为 2*maxn 个
int li[maxn];
int ri[maxn];
int hash[maxn<<3];  //数组内容为区间端点,而下标对应离散化后对应的点
bool used[maxn];    //标记该张海报是否已经算过
int num;            //最终结果

void PushDown(int rt){
if( segT[rt] != -1 ){
segT[rt<<1] = segT[rt<<1|1] = segT[rt];
segT[rt] = -1;
}
}
void update(int L,int R,int c,int l,int r,int rt){
if( L<=l && r<=R ){
segT[rt] = c;
return;
}
PushDown(rt);
int m = (l+r)>>1;
if( L<=m ) update(L,R,c,lson);
if( m<R ) update(L,R,c,rson);
}
void query(int l,int r,int rt){
if( segT[rt] != -1 ){
if( !used[ segT[rt] ] )num++;
used[ segT[rt] ] = true;
return ;
}
if( l == r ) return;
int m = (l+r)>>1;
query(lson);
query(rson);
}
int binsearch(int hash[],int n,int x){  //折半查找确定离散化后对应的点
int l=0,r=n-1;
while( l<=r ){
int m = (l+r)>>1;
if( hash[m] < x )
l = m+1;
else if( hash[m] > x )
r = m-1;
else
return m;
}
return -1;
}
int main(){
// freopen("in","r",stdin);
// freopen("out","w",stdout);

int T,n;
scanf("%d",&T);
while( T-- ){
scanf("%d",&n);
int nn=0;
for(int i=0 ; i<n ; i++){
scanf("%d%d",&li[i],&ri[i]);
hash[nn++] = li[i];
hash[nn++] = ri[i];
}
sort(hash,hash+nn);
int m = 1;
for(int i=m ; i<nn ; i++){  //踢出重复的点
if( hash[i] != hash[i-1] )
hash[m++] = hash[i];
}
for(int i=m-1 ; i>0 ; i--){  //在每个点后新加一个其后的点,保证不会因为离散化而压缩掉本来应该存在的区间
if( hash[i] != hash[i-1]+1 )
hash[m++] = hash[i]+1;
}
sort(hash,hash+m);
memset(segT , -1 , sizeof(segT));
for(int i=0 ; i<n ; i++){
int l = binsearch(hash,m,li[i]);
int r = binsearch(hash,m,ri[i]);
update(l,r,i,0,m-1,1);
}
num = 0;
memset(used,false,sizeof(used) );
query(0,m-1,1);
printf("%d\n",num );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: