poj 2528

要贴一些海报,由于宽度一样,看成 一些 线段 ,区间分别为 [L,R],按顺序贴海报,会覆盖,要问最后可以看到几张海报。。

线段树区间更新是很明显的,但是由于 数据 很大,不能直接搞,需要进行离散化处理

所谓离散化,就是 通过 处理将数据 化小,但是 保持 数据之间的大小关系。。

如  10 11 12 13  ===>  1 2 3 4

这个题目需要注意一点,就是 不能直接离散化,否则会造成错误

如 [ 1  ,9 ]   [  1 , 3 ]   [ 5 , 9 ] ==> [ 1  , 4 ]    [1 , 2 ]   [ 3  ,  4 ] ,这样结果 是 第一条线段被完全覆盖,但是实际上它 并没有 被完全覆盖

那么 我们 可以 在 1 3 5 9 中 比较的时候 出入一些数 1 (2) 3 (4) 5(6)7,在 相差大于 1 的两个数中间插入 一个夹在中间的数,就不会错了。。

#include<iostream>
#include<algorithm>
using namespace std;

#define MAXN 50005
#define lson u<<1
#define rson u<<1|1

int ll[MAXN],rr[MAXN];
int dat[MAXN],cnt[MAXN<<2];

struct Node{
	int lef,rig,delta,color;
}T[MAXN<<2];

void Build(int u,int l,int r){
	T[u].lef=l;
	T[u].rig=r;
	T[u].delta=0;
	if(l==r){T[u].color=0;return;}
	int mid=(l+r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
}

void Update(int u,int l,int r,int v){
	if(l<=T[u].lef&&T[u].rig<=r){
		T[u].delta=v;
		T[u].color=v;
	}
	else {
		if(T[u].delta){
			T[lson].delta=T[u].delta;
			T[rson].delta=T[u].delta;
			T[lson].color=T[u].delta;
			T[rson].color=T[u].delta;
			T[u].delta=0;
		}
		if(r<=T[lson].rig)Update(lson,l,r,v);
		else if(l>=T[rson].lef)Update(rson,l,r,v);
		else {
			Update(lson,l,T[lson].rig,v);
			Update(rson,T[rson].lef,r,v);
		}
		T[u].color=v;
	}
}

void Query(int u){
	if(T[u].lef==T[u].rig){cnt[T[u].color]++;return;}
	if(T[u].delta){
		T[lson].delta=T[u].delta;
		T[rson].delta=T[u].delta;
		T[lson].color=T[u].delta;
		T[rson].color=T[u].delta;
		T[u].delta=0;
	}
	Query(lson);
	Query(rson);
}

int bsearch(int low,int high,int v){
	while(low<high){
		int mid=(low+high)>>1;
		if(dat[mid]==v)return mid;
		if(dat[mid]>v)high=mid;
		else low=mid+1;
	}
	return -1;
}

int main(){
	int t;
	int N;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&N);
		int id=0,i,len;
		for(i=0;i<N;i++){
			scanf("%d%d",&ll[i],&rr[i]);
			dat[id++]=ll[i];
			dat[id++]=rr[i];
		}
		sort(dat,dat+id);
		for(len=1,i=1;i<id;i++){
			if(dat[i]!=dat[i-1])dat[len++]=dat[i];
		}
		for(i=len-1;i>0;i--){
			if(dat[i]!=dat[i-1]+1)dat[len++]=dat[i-1]+1;
		}
		sort(dat,dat+len);
		dat[len]=1000000000;
		//for(i=0;i<len;i++){printf("%d ",dat[i]);}puts("");
		Build(1,1,len);
		memset(cnt,0,sizeof(cnt));
		for(i=0;i<N;i++){
			int L=bsearch(0,len,ll[i])+1;
			int R=bsearch(0,len,rr[i])+1;
			//printf("L%d R%d\n",L,R);
			Update(1,L,R,i+1);
		}
		Query(1);
		int ans=0;
		for(i=1;i<=len;i++)
			if(cnt[i])ans++;
			printf("%d\n",ans);
	}
}


你可能感兴趣的:(poj 2528)