线段树—离散化压缩空间优化
来源:互联网 发布:微信域名案 编辑:程序博客网 时间:2024/06/06 15:52
离散化是为了优化线段树的空间。
当遇到空间需求非常大时,可以考虑用离散化,这样能大大压缩空间。
例题:(来源 poj 2528)
【题目描述】有L(L没有给出)段线段(编号为1~L) 1~1000 0000(数组无法定义几千万,所以要用离散化),有 n次操作(1 <= n<= 1 0000),每次操作都是给出l和r,第i次操作的意义就是:把第l段到第r段的线段染色为颜色i。
【输入格式】第一行给出T,表示有T组数据。每组数据给出n表示下来有n个操作。下来n个操作,每行两个整数(l,r)表示把第l段到第r段的线段染色为颜色i。注意后面的染的颜色会覆盖前面的染的颜色。
【输出格式】问最后可以看到的有多少种不一样的颜色。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int len; bool v[10010]; struct node1 { int l,r,lc,rc,c;//c=-1时,表示它的范围里海报种类不一;\ c=0 时,表示它的范围里没有海报;\ c>0 时,表示它的范围里海报种类为c。 }tr[80010];//80010 > 2*40000 > 2*b[2*n].z struct node2//离散化用结构体 { int x,p,z;//x表示原来的值,\ z表示离散化后的值,\ p表示x在原来的位置。 }a[20010],b[20010],tmp;</span><pre name="code" class="cpp"> void erfen(int l,int r)//以b[i].x为排序依据,将它从小到大排序 { int x=l,y=r,m=b[(l+r)/2].x; while(x<=y) { while(b[x].x<m) x++; while(b[y].x>m) y--; if(x<=y) { tmp=b[x]; b[x]=b[y]; b[y]=tmp; x++;y--; } } if(l<y) erfen(l,y); if(x<r) erfen(x,r); } void bt(int l,int r) { len++; int now=len; tr[now].l=l;tr[now].r=r;tr[now].lc=tr[now].rc=-1;tr[now].c=0; if(l<r) { int mid=(l+r)/2; tr[now].lc=len+1; bt(l,mid); tr[now].rc=len+1; bt(mid+1,r); } } void change(int now,int l,int r,int k) { //if(tr[now].c==k) return ; if(tr[now].l==l&&tr[now].r==r) { tr[now].c=k; return ; } int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(tr[now].c>0) tr[lc].c=tr[rc].c=tr[now].c; if(r<=mid) change(lc,l,r,k); else if(mid+1<=l) change(rc,l,r,k); else { change(lc,l,mid,k); change(rc,mid+1,r,k); } if(tr[lc].c==tr[rc].c&&tr[lc].c>0) tr[now].c=tr[lc].c; else tr[now].c=-1; } void wen(int now,int l,int r) { if(tr[now].c>=0) { v[tr[now].c]=true; return ; } int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(tr[now].c>0) tr[lc].c=tr[rc].c=tr[now].c; if(r<=mid) wen(lc,l,r); else if(mid+1<=l) wen(rc,l,r); else { wen(lc,l,mid); wen(rc,mid+1,r); } } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&a[2*i-1].x,&a[2*i].x); a[2*i-1].p=2*i-1; a[2*i].p=2*i; } //离散化 for(int i=1;i<=2*n;i++) b[i]=a[i]; erfen(1,2*n); b[1].z=1;//分配离散值 for(int i=2;i<=2*n;i++) { if(b[i].x==b[i-1].x) b[i].z=b[i-1].z;//相同值的离散值相同 else if(b[i].x-b[i-1].x>1) b[i].z=b[i-1].z+2;//难点。保留段与段之间的空位 else b[i].z=b[i-1].z+1; } for(int i=1;i<=2*n;i++) a[b[i].p].z=b[i].z;//将离散值转给对应的a for(int i=1;i<=2*n;i++) a[b[i].p].z=b[i].z;//将离散值转给对应的a //线段树 len=0; bt(1,b[2*n].z); for(int i=1;i<=n;i++) change(1,a[2*i-1].z,a[2*i].z,i); memset(v,false,sizeof(v)); wen(1,1,b[2*n].z); int ans=0; for(int i=1;i<=n;i++) { if(v[i]==true) ans++; } printf("%d\n",ans); } return 0; }
0 0
- 线段树—离散化压缩空间优化
- 离散化压缩线段树
- 【dp+离散化+线段树优化】Paint
- 线段树+区间压缩映射(离散化)
- 线段树+离散化
- 离散化 + 线段树
- 线段树离散化
- 线段树离散化
- POJ 3298(用unique离散化优化zkw线段树)
- UESTC 1501 - Defense Lines 离散化+线段树优化DP
- codeforces 271E 离散化+线段树,dp优化
- hdu 3450 离散化+dp+线段树优化
- 【NOI2016T4】区间-线段树+离散化+决策单调性优化
- POJ_2528 线段树+离散化
- HDU3577 离散化+线段树
- poj2528 线段树+离散化
- poj2528线段树+离散化
- hdu4325线段树+离散化
- Bash One-Liners Explained 译文(一)(转载自团子的小窝)
- Mybatis工作机制源码分析—一次insert请求处理流程
- Charles如何抓取http/https请求
- initializer_list 简单使用
- C语言 scanf中“%*c”什么意思?
- 线段树—离散化压缩空间优化
- iOS UIKit Dynamics使用方法
- 一些小经验
- mobile-calendar一个PC和手机移动端自适应相应式的input弹出选择日历空间
- zoj2345
- CSS 外边距(margin)重叠及防止方法
- Android学习笔记(3)-返回数据给上一个活动
- opengl 学习之路
- oracle分组排序