码迷,mamicode.com
首页 > 其他好文 > 详细

poj2528 Mayor's posters(线段树,离散化)

时间:2015-07-10 19:11:30      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:poj

离散化的思想:
对于这样的数据
(3,10000),
(9,1000000),
(5,100000),
(1,1000),
(7,1000000)
我们可以将其处理为
(2,7),
(5,9),
(3,8),
(1,6),
(4,9)
技术分享
技术分享
我们再对离散化之后的数据进行处理就行了。
题目意思:

n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。

求出最后还能看见多少张海报。

参考代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int MAXN = 10000+5;
struct Node{
	int l,r;
	int c;
}tree[14*MAXN];	//线段树
struct Seg{
	int l,r;
}s[MAXN];	//存储报纸的范围
struct Seg2{
	int p;
	int index;
}a[2*MAXN];	//存放端点信息
bool cmp(Seg2 x,Seg2 y){
	return x.p<y.p;
}
int color[2*MAXN];
int ans=0;
void build(int node,int l,int r){
	tree[node].l=l,tree[node].r=r,tree[node].c=0;
	if (l==r) return;
	build(node*2,l,(l+r)/2);
	build(node*2+1,(l+r)/2+1,r);
}
void update(int node,int l,int r,int v){
	//cout<<l<<" "<<r<<endl;
	if (tree[node].l>=l && tree[node].r<=r){
		tree[node].c=v;
		return;
	}
	if (tree[node].c>0){
		tree[2*node].c=tree[2*node+1].c=tree[node].c;
		tree[node].c=0;
	}
	int mid=(tree[node].l+tree[node].r)/2;
	if (r<=mid)
		update(2*node,l,r,v);
	else if (mid<l)
		update(2*node+1,l,r,v);
	else{
		update(2*node,l,mid,v);
		update(2*node+1,mid+1,r,v);
	}
}
void count(int node){
	if (tree[node].c>0){
		if (color[tree[node].c]==0){
			ans++;
			color[tree[node].c]++;
		}
		return;
	}
	if (tree[node].l==tree[node].r)
		return;
	count(2*node);
	count(2*node+1);
}
void solve(int n,int t){
	build(1,1,t);
	//cout<<"--------"<<endl;
	for (int i=1;i<=n;i++){
		update(1,s[i].l,s[i].r,i);
		//cout<<"123456789\n";
	}
	ans=0;
	memset(color,0,sizeof(color));
	count(1);
	printf("%d\n",ans);
}
int main(){
	int t,n;
	scanf("%d",&t);
	while (t--){
		scanf("%d",&n);
		for (int i=1;i<=n;i++){
			scanf("%d%d",&s[i].l,&s[i].r);
			a[2*i-1].p=s[i].l;
			a[2*i-1].index=i;	//标记为左端点
			a[2*i].p=s[i].r;
			a[2*i].index=-i;	//标记为右端点
		}
		sort(a+1,a+2*n+1,cmp);
		//数据离散化
		int t=1;
		int tmp=a[1].p;
		for (int i=1;i<=2*n;i++){
			if (tmp!=a[i].p){
				tmp=a[i].p;
				t++;
			}
			if (a[i].index>0)
				s[a[i].index].l=t;
			else
				s[-a[i].index].r=t;
		}
		/*
		for (int i=1;i<=n;i++){
			printf("%d %d\n",s[i].l,s[i].r);
		}
		*/
		solve(n,t);
	}
	return 0;
}


n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。

求出最后还能看见多少张海报。

版权声明:本文为博主原创文章,未经博主允许不得转载。

poj2528 Mayor's posters(线段树,离散化)

标签:poj

原文地址:http://blog.csdn.net/codeforcer/article/details/46832563

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!