POJ 2528 Mayor's posters 离散化线段树

终于知道离散化是什么东西了.....

/******************************************
离散过程
(1-8) (1-3) (6-8)
出现了1 3 6 8
    ->1 2 3 4
海报即变为
(1-4) (1-2) (3-4)
******************************************/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid (l+r)>>1
const  int maxn=1000003;
int sum[maxn<<2];
int t,x[maxn],y[maxn],i,X[maxn<<2],flag[maxn<<2],ans;
void pushdown(int rt){
	if(sum[rt]){
		sum[rt<<1]=sum[rt<<1|1]=sum[rt];
		sum[rt]=0;
	}
}
void update(int L,int R,int num,int l,int r,int rt){
	if(L<=l&&r<=R){
		sum[rt]=num;   //标记海报种类
		return ;
	}
	pushdown(rt);//向下更新
	int m=mid;
	if(L<=m) update(L,R,num,lson);
	if(m<R) update(L,R,num,rson);
}
void query(int l,int r,int rt){
	if(l==r){
		if(!flag[sum[rt]]&&sum[rt]!=0){
			ans++;
			flag[sum[rt]]=1;//数量+1 标记
		}
		return;
	}
	else if(sum[rt]){
		if(!flag[sum[rt]]){
			ans++;flag[sum[rt]]=1;//数量+1 标记
		}
		return;
	}
	int m=mid;
	query(lson);   query(rson);
}
int findx(int x,int n,int q[])//二分查找位置;
{
	int l=1,r=n;
	while(l<=r){
		int m=(l+r)>>1;
		if(x==X[m])
			return m;
		else if(x<X[m])
			r=m-1;
		else l=m+1;
	}
	return 0;

}
int main()
{
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		int num=1;
		for(i=1;i<=n;i++){
			scanf("%d%d",&x[i],&y[i]);
			X[num++]=x[i];//起点   
			X[num++]=y[i];//终点
		}
		int r=1;
		sort(X+1,X+num);
		for(i=1;i<num;i++){
			if(X[i]!=X[i+1])
				X[r++]=X[i];//去重点
		}
		r--;//还剩下几个数
		memset(sum,0,sizeof(sum));
		for(i=1;i<=n;i++)
			update(findx(x[i],r,X),findx(y[i],r,X),i,1,r,1);//findx(二分)找到海报 离散化后的位置
		memset(flag,0,sizeof(flag));
		ans=0;
		query(1,r,1);
		printf("%d\n",ans);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值