POJ 2528:Mayor's posters(线段树区间更新+离散化)
来源:互联网 发布:java poi excel 编辑:程序博客网 时间:2024/06/05 20:25
题目链接:http://poj.org/problem?id=2528
题目翻译:有一块宽度挺大的面板(宽度1e7),然后往墙上粘贴和面板相同高度的海报,但是宽度可能不同。
有N张海报,给出N张海报的起始位置和终止位置。问最后面板上可视的海报有多少个?
解题思路:
原来每想那么多,还是普通线段树写,宽度1e7,真的过不去。呵呵,感觉自己好傻好天真。
然后网上找了题解,说了和离散化有关,没有做过离散化的题目,看了以下,说是如果真的以
面板建线段树,数据太大,主要思想是将所有海报的起始和终止位置放在一起然后排序,根据
排序结果逐个编号,然后根据每个点的左右区间的编号构建线段树。但是他们都说普通离散化
处理这个题目是不对的。
【1,10】 【1,4】 【5,10】
排完序: 1 4 5 10
离散化后: 【1,4】 【1,2】 【3,4】
对于这组数据离散化后是正确的。
【1,10】 【1,4】 【6,10】 这组数据【5,5】会露出来。
离散化后:【1,4】 【1,2】 【3,4】 这个离散化后,结果是2,但是实际答案就是3,求出结
果不正确。
所以离散的时候,如果排序后,相邻两个数字间相差超过1,就在两个数字间加上一个数字(该数字为
这两个数字之间的数字)这样就可以了。
至于离散化,回头还得好好看看,其实还是没完全搞清楚,为啥这样离散化后可以与原来的等价。
AC代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#define lchild left,mid,root<<1#define rchild mid+1,right,root<<1|1using namespace std;const int maxn = 10010;const int maxm = 1e7+10;struct Point { int x,y;}p[maxn];int ans,N;int num[maxn<<4];int m[maxn<<4];int lazy[maxn<<4];int vis[maxm];void push_down(int left,int right,int root) { if(lazy[root]) { lazy[root<<1] = lazy[root]; lazy[root<<1|1] = lazy[root]; lazy[root] = 0; }}void update(int L,int R,int color,int left,int right,int root) { if(L<=left && right<=R) { lazy[root] = color; return; } push_down(left,right,root); int mid = (left+right)>>1; if(L<=mid) update(L,R,color,lchild); if(R>mid) update(L,R,color,rchild);}void query(int left,int right,int root){ if(lazy[root]) { if(vis[lazy[root]]==0) ans++; vis[lazy[root]] = 1; return; } if(left == right) return; int mid = (left+right)>>1; query(lchild); query(rchild);}int binarySearch(int len,int x) { int L,R,mid; L = 1; R = len; while(L<=R) { mid = (L+R)>>1; if(m[mid]==x) return mid; if(m[mid]>x) { R = mid-1; } else { L = mid+1; } } return -1;}int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&N); int cnt = 0; memset(vis,0,sizeof(vis)); for(int i = 1; i <= N; i++) { scanf("%d%d",&p[i].x,&p[i].y); if(vis[p[i].x] == 0) { num[cnt++] = p[i].x; vis[p[i].x] = 1; } if(vis[p[i].y] == 0) { num[cnt++] = p[i].y; vis[p[i].y] = 1; } } memset(lazy,0,sizeof(lazy)); memset(vis,0,sizeof(vis)); sort(num,num+cnt); int newcnt = 0; m[++newcnt] = num[0]; for(int i = 1; i < cnt; i++) { if(num[i]-num[i-1]>1) { m[++newcnt] = num[i-1]+1; } m[++newcnt] = num[i]; } ans = 0; for(int i = 1; i <= N; i++) { int L,R; L = binarySearch(newcnt,p[i].x); R = binarySearch(newcnt,p[i].y); update(L,R,i,1,newcnt,1); } query(1,newcnt,1); 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 (线段树 区间更新+离散化 经典染色问题)
- npm install --save 与 npm install --save-dev 的区别
- Hadoop2.7.2之集群搭建(单机)
- android studio 模拟器访问localhost
- Android集成微信支付SDK
- Java排序之【快速排序】
- POJ 2528:Mayor's posters(线段树区间更新+离散化)
- Collections工具类
- Android集成Paypal
- Shell之函数-yellowcong
- u-boot-nand.lds分析
- db2 表空间backup pending
- 归纳法浅析
- 硬编码与软编码
- K-means聚类算法原理分析与实际应用案例分析(案例分析另起一篇博客)