POJ 2528 【线段树--离散化,区间覆盖】
2015-05-21 14:02
381 查看
这道题想了挺久的。。。。 TAT
听说POJ这道题的数据奇弱,所以有一种常见的离散方法也是可以过得,但是有错。
转:
**********************************************************************
给出下面两个简单的例子应该能体现普通离散化的缺陷:
例子一:1-10 1-4 5-10
例子二:1-10 1-4 6-10
普通离散化后都变成了[1,4][1,2][3,4]
线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?
例子一是完全被覆盖掉了,而例子二没有被覆盖
为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]
如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了
**********************************************************************
(⊙v⊙)嗯,是这样的。
然后之前在纠结的时,肯定用cover[rt]=1表示覆盖,cover[rt]=0表示没有覆盖,cover[rt]=cover[rt<<1]&&cover[rt<<1|1],但是这样有个问题啊,就是我在第二次放线段更新的时候。。。就不能表示叠加啦,,根本不能计算数值的嘛!
所以应该这样!
由于贴广告是不断覆盖的过程,所以我们可以这样考虑,如果从最后一个广告开始update,每次判断的就是能不能进行一次有效的update,(这次贴的广告能不能漏出来),那么任务就可以变成找到一个cover[rt]=0的区间覆盖即可。这样省了好多事啊啊!!
然后在离散的时候要注意,由于每个不相邻的数字间要加塞,所以线段树的范围可能会生生扩大一倍,所以注意maxn。
最后,我发现,,楷体比黑体好看噻!
听说POJ这道题的数据奇弱,所以有一种常见的离散方法也是可以过得,但是有错。
转:
**********************************************************************
给出下面两个简单的例子应该能体现普通离散化的缺陷:
例子一:1-10 1-4 5-10
例子二:1-10 1-4 6-10
普通离散化后都变成了[1,4][1,2][3,4]
线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?
例子一是完全被覆盖掉了,而例子二没有被覆盖
为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]
如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了
**********************************************************************
(⊙v⊙)嗯,是这样的。
然后之前在纠结的时,肯定用cover[rt]=1表示覆盖,cover[rt]=0表示没有覆盖,cover[rt]=cover[rt<<1]&&cover[rt<<1|1],但是这样有个问题啊,就是我在第二次放线段更新的时候。。。就不能表示叠加啦,,根本不能计算数值的嘛!
所以应该这样!
由于贴广告是不断覆盖的过程,所以我们可以这样考虑,如果从最后一个广告开始update,每次判断的就是能不能进行一次有效的update,(这次贴的广告能不能漏出来),那么任务就可以变成找到一个cover[rt]=0的区间覆盖即可。这样省了好多事啊啊!!
然后在离散的时候要注意,由于每个不相邻的数字间要加塞,所以线段树的范围可能会生生扩大一倍,所以注意maxn。
最后,我发现,,楷体比黑体好看噻!
#include <stdio.h> #include <iostream> #include <algorithm> #include <map> using namespace std; #define maxn 20010 int a[maxn<<1]; map<int,int>mapp; struct node { int l,r; }que[maxn]; int cover[maxn<<3]; void create(int l,int r,int rt) { cover[rt]=0; if(l==r) return; int mid=(l+r)>>1; create(l,mid,rt<<1); create(mid+1,r,rt<<1|1); } int update(int ll,int rr,int l,int r,int rt) { if(cover[rt]) return 0; if(ll==l&&rr==r) { cover[rt]=1; return 1; } int mid=(l+r)>>1,ret=0; if(rr<=mid) ret=update(ll,rr,l,mid,rt<<1); else if(ll>mid) ret=update(ll,rr,mid+1,r,rt<<1|1); else { ret=update(ll,mid,l,mid,rt<<1); ret|=update(mid+1,rr,mid+1,r,rt<<1|1); } if(cover[rt<<1]&&cover[rt<<1|1]) cover[rt]=1; return ret; } int main() { int T; cin>>T; while(T--) { int n,top=0,ans=0; cin>>n; for(int i=0;i<n;i++) { int j,k; cin>>j>>k; que[i].l=j,que[i].r=k; a[top++]=j;a[top++]=k; } sort(a,a+top); int count=unique(a,a+top)-a; int ncount=0; //create(0,count-1,1); for(int i=0,j=0;i<count;i++,j++) { if(a[i]-1>a[i-1]) j++; mapp[a[i]]=j; //printf("map[%d]=%d\n",a[i],j); ncount=j; } create(0,ncount,1); for(int i=n-1;i>=0;i--) if(update(mapp[que[i].l],mapp[que[i].r],0,ncount,1)) ans++; cout<<ans<<endl; } return 0; }
相关文章推荐
- poj 2528 Mayor's posters(线段树区间覆盖、离散化)
- POJ 2528(线段树,区间覆盖,离散化思想)
- POJ 2528 Mayor's posters 线段树的区间覆盖 离散化
- POJ 2528 Mayor's posters (线段树 区间更新+离散化)
- POJ 2528 Mayor's posters(离散化+区间set线段树)
- poj 2528 Mayor's posters(线段树+区间离散化)
- poj-----(2528)Mayor's posters(线段树区间更新及区间统计+离散化)
- POJ 2528 Mayor's posters(线段树,区间覆盖,单点查询)
- poj 2528 Mayor's posters(线段树 离散化 区间更新 贴海报)
- POJ 2528:Mayor's posters(线段树区间更新+离散化)
- POJ 2528 Mayor's posters // 线段树 区间更新 离散化
- POJ 2528 Mayor's posters (线段树区间更新、离散化)
- POJ 2528 Mayor's posters - 线段树区间更新+离散化
- POJ 2528-Mayor's posters(线段树区间染色+离散化)
- POJ 2528 区间端点离散化,线段树区间更新
- POJ 2528 Mayor's posters (线段树区间赋值 + 离散化)
- POJ 2528 Mayor's posters(线段树/区间更新 离散化)
- POJ 2528 Mayor's posters 区间离散化线段树
- poj 2528 线段树+离散化+有颜色的区间覆盖
- POJ 2528 Mayor's posters(线段树/区间更新 离散化)