您的位置:首页 > 其它

【POJ 2528】Mayor’s posters(线段树+离散化)

2016-07-22 01:56 423 查看

题目

给定每张海报的覆盖区间,按顺序覆盖后,最后有几张海报没有被其他海报完全覆盖。
离散化处理完区间端点,排序后再给相差大于1的相邻端点之间再加一个点,再排序。
线段树,tree[i]表示节点i对应区间是哪张海报,如果是-1代表对应区间不是一张海报(0或多张)。
每贴一张海报,就用二分查找出覆盖的起点和终点对应的离散后的下标,然后更新区间。
线段树的区间更新可以加上懒惰标记(或延迟标记,但是这题可以不用另外标记。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10005
using namespace std;
int m,li
,ri
;
int x[N<<3],tree[N<<4],ans;
bool hash
;
void PushDown(int node){
tree[node<<1]=tree[node<<1|1]=tree[node];
tree[node]=-1;
}
void Update(int v,int l,int r,int node,int L,int R){
if(L>r||R<l)return;
if(L<=l&&r<=R){
tree[node]=v;
return;
}

if(tree[node]!=-1) PushDown(node);
int m=l+r>>1;
Update(v,l,m,node<<1,L,R);
Update(v,m+1,r,node<<1|1,L,R);
}
void query(int l,int r,int node){
if(l==r){
if(tree[node]!=-1&&!hash[tree[node]]){
ans++;
hash[tree[node]]=1;
}
return;
}
if(tree[node]!=-1)PushDown(node);
int m=l+r>>1;
query(l,m,node<<1);
query(m+1,r,node<<1|1);
}
int main(){
freopen("in.txt","r",stdin);
int t,n,i;
scanf("%d",&t);
while(t--){
memset(tree,-1,sizeof tree);
memset(hash,0,sizeof hash);
int k=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&li[i],&ri[i]);
x[++k]=li[i];
x[++k]=ri[i];
}
sort(x+1,x+k+1);
m=1;
for(i=2;i<=k;i++){
if(x[i]!=x[i-1])x[++m]=x[i];
}
for(i=m;i>1;i--){
if(x[i]-x[i-1]>1)x[++m]=x[i]-1;
}
sort(x+1,x+m+1);
for(i=1;i<=n;i++){
int l=lower_bound(x+1,x+m,li[i])-x;
int r=lower_bound(x+1,x+m,ri[i])-x;
Update(i,1,m,1,l,r);
}
ans=0;
query(1,m,1);
printf("%d\n",ans);
}
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: