博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2528 Mayor's posters 线段树+离散化
阅读量:5113 次
发布时间:2019-06-13

本文共 2395 字,大约阅读时间需要 7 分钟。

离散化 的大概思路 :   比如说给你一组 数据 1 4 1000 100000,  如果直接

                         开线段, 显然是浪费, 那么我们只要 进行 映射 :
                                1    1  
                                4    2
                             1000    3
                           100000    4
                         接下来 我们只要对 1 2 3 4 建立线段树就行了 只需要
                         [1,4]的区间     
离散化就相当于是先做映射,然后再建树。

本题大意:给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张?

海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间。

如果直接建树,就算不TLE,也会MLE。即单位区间长度太多。

其实10000张海报,有20000个点,最多有19999个区间。对各个区间编号,就是离散化。然后建数。

其实浮点数也是一样离散化的。

 

 

刚开始离散化利用map,果断tle了

改了就过了

 

#include
#include
#include
#include
#define ll long long#define ull unsigned long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=20000+20;struct Seg{ int l,r;};Seg seg[maxn>>1];struct Gao{ int v,dir,id,num;};Gao gao[maxn];bool vis[maxn>>1];int val[maxn<<2];int lazy[maxn<<2];int ans;int solve(int ,int );int main(){ int test; scanf("%d",&test); while(test--){ int n; scanf("%d",&n); int len=0; for(int i=1;i<=n;i++){ int u,v; scanf("%d %d",&u,&v); seg[i].l=u,seg[i].r=v; gao[++len].v=u,gao[len].dir=0,gao[len].id=i; gao[++len].v=v,gao[len].dir=1,gao[len].id=i; } printf("%d\n",solve(n,len)); } return 0;}bool cmp(Gao x,Gao y){ return x.v
=r){ lazy[rt]=add; val[rt]=add; return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,add,lson); if(R>m) update(L,R,add,rson); pushup(rt);}void query(int l,int r,int rt){ if(!val[rt]) return ; if(val[rt]>0){ if(!vis[val[rt]]){ ans++; vis[val[rt]]=true; } return ; } pushdown(rt); int m=(l+r)>>1; query(lson); query(rson);}int solve(int n,int len){ sort(gao+1,gao+len+1,cmp); int tot=0; gao[1].num=++tot; for(int i=2;i<=len;i++){ if(gao[i].v==gao[i-1].v) gao[i].num=tot; else gao[i].num=++tot; } for(int i=1;i<=len;i++){ if(!gao[i].dir){ seg[gao[i].id].l=gao[i].num; } else{ seg[gao[i].id].r=gao[i].num; } } memset(val,0,sizeof val); memset(lazy,0,sizeof lazy); for(int i=1;i<=n;i++){ update(seg[i].l,seg[i].r,i,1,tot,1); } memset(vis,false,sizeof vis); ans=0; query(1,tot,1); return ans;}

 

转载于:https://www.cnblogs.com/-maybe/p/4844234.html

你可能感兴趣的文章
文件流的使用以及序列化和反序列化的方法使用
查看>>
Android-多线程AsyncTask
查看>>
第一个Spring冲刺周期团队进展报告
查看>>
红黑树 c++ 实现
查看>>
Android 获取网络链接类型
查看>>
linux中启动与终止lnmp的脚本
查看>>
gdb中信号的处理[转]
查看>>
LeetCode【709. 转换成小写字母】
查看>>
如何在Access2007中使用日期类型查询数据
查看>>
Jzoj4757 树上摩托
查看>>
CF992E Nastya and King-Shamans(线段树二分+思维)
查看>>
oracle 几个时间函数探究
查看>>
第一个Java Web程序
查看>>
树状数组_一维
查看>>
如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:
查看>>
linux install ftp server
查看>>
嵌入式软件设计第8次实验报告
查看>>
算法和数据结构(三)
查看>>
Ubuntu下的eclipse安装subclipse遇到没有javahl的问题...(2天解决了)
查看>>
alter database databasename set single_user with rollback IMMEDIATE 不成功问题
查看>>