标签:poj
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 49385 | Accepted: 14304 |
Description
Input
Output

Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
Source
有一条1到10的数轴(长度为9),给定4个区间[2,4] [3,6] [8,10] [6,9],覆盖关系就是后者覆盖前者,每个区间染色依次为 1 2 3 4。
现在我们抽取这4个区间的8个端点,2 4 3 6 8 10 6 9
然后删除相同的端点,这里相同的端点为6,则剩下2 4 3 6 8 10 9
对其升序排序,得2 3 4 6 8 9 10
然后建立映射
2 3 4 6 8 9 10
↓ ↓ ↓ ↓ ↓ ↓ ↓
1 2 3 4 5 6 7
那么新的4个区间为 [1,3] [2,4] [5,7] [4,6],覆盖关系没有被改变。新数轴为1到7,即原数轴的长度从9压缩到6,显然构造[1,7]的线段树比构造[1,10]的线段树更省空间,搜索也更快,但是求解的结果却是一致的。(以上我是复制别人的= = ,自己也是第一次接触离散化,只是觉得他讲的很通俗。)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define M 10050
using namespace std;
struct post{
int l,r;
}post[M];
int x[M<<1],ans,a[M<<4];
int tohash[10000005];
struct tree{
int l,r,color;
}tree[1000005];
void build(int l,int r,int root)
{
tree[root].l=l;
tree[root].r=r;
tree[root].color=-1; //初始化赋为-1
if(l==r)return ;
int mid=l+r>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
}
void pushdown(int root){ //如果一个区间里面的颜色有多种,就认为color是-1
if(tree[root].color!=-1)
{tree[root<<1].color=tree[root<<1|1].color=tree[root].color;
tree[root].color=-1;
}
return;
}
void update(int l,int r,int z,int root)
{
if(l==tree[root].l&&tree[root].r==r){
tree[root].color=z;
return ;
}
pushdown(root);
int mid=tree[root].l+tree[root].r>>1;
if(r<=mid)update(l,r,z,root<<1);
else if(l>mid)update(l,r,z,root<<1|1);
else {
update(l,mid,z,root<<1);
update(mid+1,r,z,root<<1|1);
}
}
void query(int root)
{
int flag,j;
if(tree[root].color!=-1){ //如果当前区间不是多种颜色,就直接添加入数组。
a[ans++]=tree[root].color;
return;
}
if(tree[root].l==tree[root].r)return;
query(root<<1);
query(root<<1|1);
return;
}
int main()
{
int T,i,j,k,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
j=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&post[i].l,&post[i].r);
x[j++]=post[i].l;
x[j++]=post[i].r;
}
sort(x,x+j);
j=unique(x,x+j)-x; //unique函数用于选出重复的数并放到数组最后,并返回不重复数列的末尾位置。(相当于将重复的数去掉了)
for(i=j-1;i>=0;i--)
if(x[i]!=x[i-1]+1)x[j++]=x[i-1]+1; //解决普通离散化的缺陷
sort(x,x+j);
int num=1;
for(i=0;i<j;i++)
tohash[x[i]]=num++; //离散化映射
build(1,num-1,1);
for(i=0;i<n;i++)
{
update(tohash[post[i].l],tohash[post[i].r],i+1,1);
}
memset(a,0,sizeof(a));
ans=0;
query(1);
sort(a,a+ans);
int y=1;
for(i=1;i<ans;i++)
if(a[i]!=a[i-1])y++; //这里将先前可能有重复的颜色去掉,只选不重复的颜色。
printf("%d\n",y);
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
poj 2528 Mayor's posters(线段树区间覆盖、离散化)
标签:poj
原文地址:http://blog.csdn.net/aaaaacmer/article/details/47101899