POJ 2528(线段树 区间更新 离散化)
来源:互联网 发布:网络时间校准到秒 编辑:程序博客网 时间:2024/05/22 03:45
POJ 2528
题目大意
有一排分成若干组长为1区间的墙,现在要往墙上贴n张海报,一个海报覆盖连续的L到R的区间,按照一定的顺序贴,问最后有多少海报全部或有一部分漏在了表面。
分析
由于L和R比较大但线段数目不大(最多出现20000种数字),所以需要先对数据进行一下离散化,将L和R映射到一个较小的区间.
更新操作是将一个区间全部更改这个线段的编号,这样在进行n此更新后,对每一个点进行查询看这个点属于哪个线段,最后统计以下就是答案。
技巧
(以下内容引用自:数据的离散化)
使用STL算法离散化:
思路:先排序,再删除重复元素,然后就是索引元素离散化后对应的值。
假定待离散化的序列为a[n],b[n]是序列a[n]的一个副本,则对应以上三步为:
sort(sub_a,sub_a+n);int size=unique(sub_a,sub_a+n)-sub_a;//size为离散化后元素个数
for(i=0;i<n;i++) a[i]=lower_bound(sub_a,sub_a+size,a[i])-sub_a + 1;//k为b[i]经离散化后对应的值
对于第3步,若离散化后序列为0, 1, 2, …, size - 1则用lower_bound,从1, 2, 3, …, size则用upper_bound,其中lower_bound返回第1个不小于b[i]的值的指针,而upper_bound返回第1个大于b[i]的值的指针,当然在这个题中也可以用lower_bound然后再加1得到与upper_bound相同结果,两者都是针对以排好序列。使用STL离散化大大减少了代码量且结构相当清晰。
代码
#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>#include<map>#include<algorithm>#include<set>#include<stack>const int MAXN=100005;//线段数int n;int info[MAXN*4];//线段树维护的信息int lenth;int bj[MAXN*2];int num[MAXN*2];//用于保存离散化信息int cnt;using namespace std;struct LINE{ int a; int b;}line[MAXN];void Init(){ cnt=0; lenth=0; memset(bj,0,sizeof(bj)); memset(info,0,sizeof(info));}void Pushdown(int rt)//下推延迟信息,该节点的信息已更新{ if(info[rt]) { info[rt*2]=info[rt]; info[rt*2+1]=info[rt]; info[rt]=0; }}void Update(int L,int R,int C,int l,int r,int rt)//保证(L,R)区间的数将会更新为C{ if(L<=l && r<=R){info[rt]=C;return ;} int m=(l+r)/2; Pushdown(rt); if(L<=m)Update(L,R,C,l,m,rt*2); if(R>m)Update(L,R,C,m+1,r,rt*2+1);}int Query(int x,int l,int r,int rt)//查询第x个数是什么{ if(l==r)return info[rt]; int m=(l+r)/2; Pushdown(rt); if(x<=m)return Query(x,l,m,rt*2); else if(x>m)return Query(x,m+1,r,rt*2+1);}void Solve(){ int t; int ans=0; for(int i=1;i<=lenth;i++) { t=Query(i,1,lenth,1); bj[t]=1; } for(int i=1;i<=lenth;i++)ans+=bj[i]; printf("%d\n",ans);}int main(){ int T; int a,b; scanf("%d",&T); while(T--) { Init(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); num[++cnt]=a; num[++cnt]=b; line[i].a=a;line[i].b=b; } sort(num+1,num+cnt+1); int m=unique(num+1,num+cnt+1)-num-1;//unique返回去重后尾地址,但那个地址不含数字,m表示去重后的个数 int t=m; for(int i=2;i<=t;i++)//如果两个数相差大于1则在他们之间插入一个数 { if(num[i]-num[i-1]>1) num[++m]=num[i-1]+1; } sort(num+1,num+m+1); int x,y; lenth=m; for(int i=1;i<=n;i++) { x=lower_bound(num+1,num+m+1,line[i].a)-num;//lower_bound返回第1个不小于line[i].a的值的指针 y=lower_bound(num+1,num+m+1,line[i].b)-num; Update(x,y,i,1,lenth,1); } Solve(); } return 0;}
0 0
- POJ 2528 区间端点离散化,线段树区间更新
- poj 2528 线段树离散化+区间更新
- poj 2528 线段树数据离散化+区间更新
- POJ 2528(线段树 区间更新 离散化)
- poj-2528-线段树离散化区间
- 线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters
- POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)
- POJ 2528(summer III X) 区间离散化,线段树区间更新
- 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 (线段树区间更新+离散化)
- Java:java语句的执行结构、分支结构
- #1050 :求多叉树中的的最长路
- Xml中获取子节点的值
- Apache
- Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
- POJ 2528(线段树 区间更新 离散化)
- 1
- Magento 1.x 入门之系列教程一
- NoTitleBar找不到&NoTitleBar不属于&加载不了NoTitleBar
- Android 之 BroadcastReceiver (一) 相关知识
- Android基础之知识体系
- 2
- TREC Real-Time Summarization Track
- 不是每个人都可以是程序员