POJ2528,线段树+离散化
来源:互联网 发布:php相册源码 编辑:程序博客网 时间:2024/05/17 00:55
题目链接:
POJ2528
Mayor's posters
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 50574 Accepted: 14658
Description
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules:
They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters' size, their place and order of placement on the electoral wall.
- Every candidate can place exactly one poster on the wall.
- All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown).
- The wall is divided into segments and the width of each segment is one byte.
- Each poster must completely cover a contiguous number of wall segments.
They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters' size, their place and order of placement on the electoral wall.
Input
The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i-th line among the n lines contains two integer numbers li and ri which are the number of the wall segment occupied by the left end and the right end of the i-th poster, respectively. We know that for each 1 <= i <= n, 1 <= li <= ri <= 10000000. After the i-th poster is placed, it entirely covers all wall segments numbered li, li+1 ,... , ri.
Output
For each input data set print the number of visible posters after all the posters are placed.
The picture below illustrates the case of the sample input.
The picture below illustrates the case of the sample input.
Sample Input
151 42 68 103 47 10
Sample Output
4
题意:
候选者在展览板上贴海报,当所有人都贴完了,有多少海报是可以被看见的(看见,可以是整幅海报都可以被看见,或者是海报的一部分可以被看见)
题解:
我觉得这道题目需要注意的是,(拿样例来说)区间[1,4],1和4不是点(可以看图)是某一块小展览板;
在离散化的时候,需要注意:(看不懂下面的话,可以先看程序,手推一组样例,然后再来理解这段话)
1 3 4 5 9一般程序对应于1 2 3 4 5(这样会导致不相邻的线段变为相邻)实际应该对应于1 3 4 5 7
线段树+离散化 就OK了
//bei#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define Maxn 12000int tol[Maxn<<4],segT[Maxn<<4],li[Maxn],ri[Maxn];//tol是用来保存所有区间的左右端点,segT是建树用的数组,li是保存区间左端点,ri是保存对应右端点bool vis[Maxn]; //用来标记哪些颜色已经统计过了int ans;int Binsearch(int key,int r,int tol[]) //二分查找位置,返回的位置就是离散化后的值{ int l = 1,m; while (l <= r) { m = (l+r) >> 1; if (tol[m] > key) r = m - 1; else if (tol[m] < key) l = m + 1; else return m; }}void PushDown(int rt) // 线段树的延迟更新{ if (segT[rt]) { segT[rt<<1] = segT[rt<<1|1] = segT[rt]; segT[rt] = 0; }}void update(int L,int R,int color,int l,int r,int rt) // 将对应区间的值更新为color,表示该段区间贴的海报{ if (L <= l && r <= R) { segT[rt] = color; return ; } PushDown(rt); // 当该区间被贴上另外的海报时,需要向下更新! int m = (l+r) >> 1; if (L <= m) update(L,R,color,lson); if (R > m) update(L,R,color,rson);}void query(int l,int r,int rt){ if (segT[rt])// 举个例子:区间[4,6]贴的是同一幅海报,假设对应color的值为2,在线段树中[4,6] 是两段区间[4,5]和[6],当统计完[4,5]之后,再统计到[6]时就不能在加一了//所以得用一个vis数组用来标记哪些颜色已经被统计过了 { if (!vis[segT[rt]]) { ++ans; vis[segT[rt]] = true; } return ; } if (l == r) return ; int m = (l+r) >> 1; query(lson); query(rson);}int main(){ int c,n,i,k; while (~scanf("%d",&c)) { while (c--) { scanf("%d",&n); k = 1; for (i = 1; i <= n; ++i) // tol数组先保存所有区间的端点值 { scanf("%d%d",&li[i],&ri[i]); tol[k++] = li[i]; tol[k++] = ri[i]; } sort(tol+1,tol+k); // 排序 int m = 2; for (i = 2; i < k; ++i) // 去掉tol数组中重复的值,因为在二分查找位置时,不能一个值可以映射成两个位置,对吧! { if (tol[i] != tol[i-1]) tol[m++] = tol[i]; } for (i = m - 1; i > 1; --i)//这步+下面的排序一起理解,目的是将原本不相邻的区间也离散成不相邻的区间(可以手推一组样例,就好理解了) { if (tol[i] != tol[i-1]+1) tol[m++] = tol[i-1] + 1; } sort(tol+1,tol+m); memset(segT,0,sizeof(segT)); for (i = 1; i <= n; ++i) { int a = Binsearch(li[i],m-1,tol);//得到该区间左端点离散后的值 int b = Binsearch(ri[i],m-1,tol); update(a,b,i,1,m-1,1);//建树,其中这段区间对应的海报color值为i,正好保证了每幅海报是不相同的 } ans = 0; memset(vis,false,sizeof(vis)); query(1,m-1,1); //查询,记得写上上面两条语句; printf("%d\n",ans); } } return 0;}
0 0
- poj2528 线段树+离散化
- poj2528线段树+离散化
- POJ2528 离散化线段树
- poj2528(线段树+离散化)
- poj2528 线段树 离散化
- poj2528离散化+线段树
- 线段树+离散化 poj2528
- poj2528 离散化+线段树
- POJ2528,线段树+离散化
- poj2528(线段树+离散化)
- poj2528线段树+离散化
- 线段树 离散化 poj2528
- poj2528(离散化+线段树)
- 离散化+线段树 poj2528
- poj2528 线段树+离散化
- poj2528 离散线段树
- poj2528 (线段树+离散化)
- poj2528 线段树加离散化
- 操作系统页面置换算法
- 浅谈abstract和interface
- 在Spring3中使用注解(@Scheduled)创建计划任务
- Linux网络编程下send到一个disconnected socket上
- 雅各比迭代法
- POJ2528,线段树+离散化
- ajax常见错误和使用总结
- android学习笔记1 - 搭建android开发环境
- 【微信】网页授权,获取CODE,OPENID,
- [LeetCode 235] Lowest Common Ancestor of a Binary Search Tree
- 自定义UITableViewCell勾选框的保持
- MySQL创建表结构里面的那个长度对于整型的作用
- oracle实现查询每一个部门的员工工资排在前三的员工的基本信息详细举例
- CAS:Compare And Swap 无锁