标签: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