POJ_Mayor's Poster_线段树、离散化
来源:互联网 发布:租车软件排行 编辑:程序博客网 时间:2024/04/29 10:18
每次A题都要听一次小苹果,感觉自己萌萌哒。
题意:
一个线段上10^7个点可以“涂色”,每个点只能涂一种,后涂覆盖先涂,离线进行最多10^5次操作,每次区间涂一种新的颜色,最后求问一共有多少中颜色。(线段上本来无色)。
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.一开始在纠结10^5次涂色怎么更新树,后来看了题解也没提,然后才想起来离线操作只要向下更新就好了,不用回溯,反正最后遍历一遍整棵树就可以。。。。。
然后题解里提了我没想到的问题,线段长达10^7,空间开销很大,10^7个int需要32*10^7 / (8*1024)K,大概4*10^4K,题目给了6*10^4K,线段树肯定会MLE。由于线段树很大,也会脱慢速度,不过O(logn)的算法速度的影响应该还不是很大。
为了解决这个问题,要用离散化操作。离散化是把较大空间的点映射到一个较小的空间里去。具体操作就是先读入所有操作,把每个操作的l和r记录,去重,然后排序,重新编号,这样原来的空间就紧凑很多了。这道题这里有个问题,不能只离散化l和r两个点,要多加他们两端的两个点,否则会过度压缩,具体什么情况POJ的discuss里有,但是我没这么处理也过了,应该是数据水。。。总不能是标程出错了吧。
在离散化的过程中我的办法不是很好,看了下空间开销,我的是4*10^4多,和预估的一样,但是很多代码都是三次方级别的空间,想了想没想到什么好的办法,用map什么的存储pair然后用二分查找,那样常数大一点但是复杂度会降下去。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<algorithm>using namespace std;#define mxn 20100#define mxl 10000010int ll[mxn<<2],rr[mxn<<2];int color[mxn<<2],flag[mxn<<2];int n,l[mxn],r[mxn];int mapp[mxl],dis[mxn];int hash;void build(int l,int r,int id){ll[id]=l,rr[id]=r,color[id]=-1,flag[id]=-1;if(l==r)return;int m=(l+r)>>1,ls=id<<1,rs=ls|1;build(l,m,ls);build(m+1,r,rs);}void down(int id);void update(int l,int r,int x,int id){if(ll[id]==l&&rr[id]==r){flag[id]=x;color[id]=x;return;}color[id]=-1;if(flag[id]!=-1)down(id);int m=(ll[id]+rr[id])>>1,ls=id<<1,rs=ls|1;if(r<=m)update(l,r,x,ls);else if(l>m)update(l,r,x,rs);else{update(l,m,x,ls);update(m+1,r,x,rs);}}void down(int id){if(ll[id]==rr[id])return;int m=(ll[id]+rr[id])>>1,ls=id<<1,rs=ls|1;update(ll[id],m,flag[id],ls);update(m+1,rr[id],flag[id],rs);flag[id]=-1;}void find(int id){if(color[id]!=-1){flag[color[id]]=1;return;}if(ll[id]==rr[id])return;int ls=id<<1,rs=ls|1;find(ls);find(rs);}int ans(){int ret=0;for(int i=0;i<n;++i)if(flag[i])++ret;return ret;}int main(){int cs;scanf("%d",&cs);while(cs--){scanf("%d",&n);memset(mapp,0,sizeof(mapp));for(int i=0;i<n;++i){scanf("%d%d",&l[i],&r[i]);dis[i*2]=l[i];//应多加两个点离散化,但是那样POJ过不过就不知道了dis[i*2+1]=r[i];}hash=0;sort(dis,dis+2*n);for(int i=0;i<2*n;++i)if(!mapp[dis[i]])mapp[dis[i]]=++hash;for(int i=0;i<n;++i){l[i]=mapp[l[i]];r[i]=mapp[r[i]];}build(1,hash,1);for(int i=0;i<n;++i)update(l[i],r[i],i,1);memset(flag,false,sizeof(flag));find(1);printf("%d\n",ans());}return 0;}
0 0
- POJ_Mayor's Poster_线段树、离散化
- 【线段树+离散化】Mayor's Posters
- 线段树+离散化Mayor's posters
- poj_2528Mayor's posters线段树+离散化
- poj2528Mayor's posters【线段树+离散化】
- poj2528Mayor's posters(线段树+离散化)
- poj2528Mayor's posters【离散化+线段树】
- 离散化+线段树 POJ 2528 (Mayor's posters)
- POJ 2528 Mayor's posters(离散化+线段树)
- poj 2528 Mayor's posters 离散化 线段树
- pku 2528 Mayor's posters-线段树+离散化
- POJ 2528 Mayor's posters 线段树+离散化
- poj 2528 Mayor's posters 线段树+离散化
- POJ 2528 Mayor's posters (线段树+离散化)
- (线段树+离散化) Mayor's post(P2528)
- POJ 2528 Mayor's posters(离散化+线段树)
- POJ 2528 Mayor's posters 线段树+离散化
- POJ 2528 Mayor's posters(线段树+离散化)
- 工厂方法模式(Factory Method)
- The Future for SharePoint: On Premises Vs Online
- TFT LCD 7寸1024*600 FPGA点亮
- Binary Tree Maximum Path Sum
- android adapter的体系
- POJ_Mayor's Poster_线段树、离散化
- 反射机制
- Selenium的PageFactory & PageObject 在大型项目中的应用
- 2.2.2新增-designMode属性
- cc150 50道高频总结
- php添加模块
- loadrunner 性能计数器解释
- linux虚拟机不识别用户密码,无法登录问题解决
- “右值引用”的补充说明