POJ 2528 Mayor's posters (线段树+离散化)
来源:互联网 发布:hbuilder for mac下载 编辑:程序博客网 时间:2024/04/27 09:17
http://poj.org/problem?id=2528
这题一定要写个题解。Orz。
不信看图,五月多做过一次,一直RE。现如今来做,仍然RE多发。
题意:在墙壁上贴广告,广告的版面有大有小,并且贴广告有先后之分,后面贴的广告会覆盖前面的广告,求解最后能看到的广告面。
本题数据太大,要用到离散化,意思是将区间范围很大的数据集映射到较小的数据集。
离散化的步骤:
- 读取一对区间(x,y),用一个结构体(这里用arr)来存储这些点:arr[i].st =x,arr[i].ed=y;同时用另外一个离散的数组has来存储这些点,has[t++]=x,has[t++]=y;
- 把has数组sort一遍
- 把has数组unique(去重)一遍
int tt=unique(has,has+t)-has; 接下来更新线段树的时候,每个值通过二分得到:
int xx= lower_bound(has,has+tt,arr[i].st)
int yy= lower_bound(has,has+tt,arr[i].ed)
update(xx,yy);然后就没有然后了 ==
只不过这题的不同的是,题目给的数字代表的是一个单位长度,而不是具体的一个点,普通的离散化会造成错误。所以在区间长度大于1的时候,往往在区间多加一个点。我省掉了这个步骤,我是在不管是否大于1,区间都在左右端点分别再加点。
这题让我RE的不是数组开大开小的问题,是一个query懒人操作没有处理好的问题。
错错更健康,以后不再错就好 ==
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define mset(x,y) memset(x,y,sizeof(x))#define lson l,mid,i<<1#define rson mid+1,r,i<<1|1using namespace std;const int N = 10000 +10;int ans;struct Node{ int st,ed;}arr[N];//记录区间的起点和终点bool vis[N];int has[N*4],tr[N*16];//注意数组范围,一定要开这么大void built(int l,int r,int i){ tr[i]=0; if(l==r) return; int mid=(l+r)>>1; built(lson); built(rson); return;}void pushdown(int i){ tr[i<<1] = tr[i<<1|1] = tr[i]; tr[i] = 0; return;}void update(int l,int r,int i,int a,int b,int x){ if(l>=a&&r<=b) { tr[i] = x; return; } if(tr[i]) pushdown(i); int mid=(l+r)>>1; if(mid>=a) update(lson,a,b,x); if(mid<b) update(rson,a,b,x); return;}void query(int l,int r,int i,int a,int b){ if(l>=a && r<=b &&tr[i]!=0) { if(vis[tr[i]]) ans++,vis[tr[i]]=false; return; } if(l==r) return;//RE多发的关键处,Orz!!! if(tr[i]) pushdown(i); int mid= (l+r)>>1; if(mid>=a) query(lson,a,b); if(mid<b) query(rson,a,b); return;}int main(){ int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); mset(has,0); int t=0; for(int i=0;i<n;i++) { scanf("%d%d",&arr[i].st,&arr[i].ed); has[t++]=arr[i].st; has[t++]=arr[i].st+1;//奇妙的地方 has[t++]=arr[i].ed; has[t++]=arr[i].ed-1;//奇妙的地方 } sort(has,has+t); int tt=unique(has,has+t)-has; built(1,tt,1); mset(vis,true); ans=0; for(int i=0;i<n;i++) { int x = lower_bound(has,has+tt,arr[i].st) - has + 1;//数组是从0开始的,所以+1保证正数性 int y = lower_bound(has,has+tt,arr[i].ed) - has + 1; update(1,tt,1,x,y,i+1); } query(1,tt,1,1,tt); printf("%d\n",ans); } return 0;}
0 0
- 离散化+线段树 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 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 离散化线段树
- selenim java判断图片有没有加载完成
- 华为OJ(名字漂亮度)
- 关于android中broadcast和BroadcastReceiver浅谈
- [LeetCode] Populating Next Right Pointers in Each Node II
- Linux之debugfs介绍
- POJ 2528 Mayor's posters (线段树+离散化)
- ADNROID XML图像资源文件详细讲解(五)
- bzoj 1199 二分暴力
- 将 res 资源文件转换成 file
- C/C++语言 void 及 void 指针深层探索
- ftp上传图片的简单用法
- aapt简介及常用命令
- 简单实现类似Spring的在任意代码中获取Request的功能
- Javadoc导出java类的文档结构小结