先讲一下:dalao @lisuier 发布的前一篇题解严格来讲是有错误的

比如下一组数据:

1
3
1 10
1 4
7 10
显然答案是3,然而用lisuier dalao的程序做出来的答案是2(后面会讲错误原因)

简单看出这道题用线段树可解

so

我们用离散化+权值线段树(戳这里详解)

实际上是安利自己博客

思路:建一棵空数,然后把某一区间的颜色更新为读入的颜色;

WA,SO EASY

OK
那我们先建一棵(10^7*4)的空树

然后

空间就炸了

正经的处理方法

对区间端点进行离散化

接下来
引用一下的 @lisuier 的话

离散化,如下面的例子,因为单位1是一个单位长度,将下面的

1 2 3 4 6 7 8 10

— — — — — — — —

1 2 3 4 5 6 7 8
离散化 X[1] = 1; X[2] = 2; X[3] = 3; X[4] = 4; X[5] = 6; X[7] =8; X[8] = 10
这样我们就优化了空间

对一般的离散化来说,这很对,

但是

再看这一组数据

1
3
1 10
1 4
7 10

用该方法离散化后

第二张海报与第三张海报中间的间隔就消...消失了

也就是说第一张海报就看不到了(手动模拟一下发现是能看到的)

处理方法:离散化时,加到临时数组b中的右端点+1也加到临时数组中

看起来是这样的

int init(){//读入并进行离散处理n = read(); tot=0;for(int i = 1;i <= n;i++) a[i].l = read(),a[i].r = read(),b[++tot] = a[i].l,b[++tot] = a[i].r,b[++tot] = a[i].r + 1;//加入右边的端点+1sort(b + 1,b + tot + 1);int len=unique(b + 1,b + tot + 1) - b - 1;for(int i = 1; i <= n;i++) a[i].l = lower_bound(b + 1,b + len + 1,a[i].l) - b,a[i].r = lower_bound(b + 1,b + len + 1,a[i].r) - b; //下面是正常的离散化return len; //离散化后总共处理多长的墙;
}

更新之类的与普通线段树差不多

但是要注意push_down操作和query操作

比如说询问时已经访问过得颜色要标记一下

接下来是

简单易懂

的代码.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define M 20005
using namespace std;
inline int read(){char chr=getchar(); int f=1,ans=0;while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}while(isdigit(chr))  {ans=ans*10;ans+=chr-'0';chr=getchar();}return ans*f;
}
int ans = 0;
struct segment
{
int l,r;
}a[10005 << 4];
bool vis[20005 << 4];
struct node
{int l,r,val,lazy,sum;int mid(){return l + r >> 1;}
}t[M << 4];
int b[20005 << 4],n,tot=0,x,y;
int init()
{//读入并进行离散处理n = read(); tot = 0;for(int i = 1;i <= n;i++) a[i].l = read(),a[i].r = read(),b[++tot] = a[i].l,b[++tot] = a[i].r,b[++tot] = a[i].r + 1;sort(b + 1,b + tot + 1);int len=unique(b + 1,b + tot + 1) - b - 1;for(int i = 1; i <= n;i++) a[i].l = lower_bound(b + 1,b + len + 1,a[i].l) - b,a[i].r = lower_bound(b + 1,b + len + 1,a[i].r) - b; return len; //离散化后总共处理多长的墙;
}
void push_down(int i){if(t[i].val == -1)  return;t[i << 1].val = t[i << 1 | 1].val = t[i].val;  t[i].val = -1;
}
void build(int i,int l,int r)
{t[i].l = l;t[i].r = r;t[i].val = 0;if(l == r){return;}int m=t[i].mid();build(i << 1,l,m);build(i << 1 | 1,m + 1,r);
}
void updata(int i,int l,int r,int x)
{if(l <= t[i].l && t[i].r <= r){t[i].val = x;return;}push_down(i);int m = t[i].mid();if(l <= m)  updata(i << 1,l,r,x);if(r > m)updata(i << 1 | 1,l,r,x);
}
void query(int i,int l,int r)
{if(t[i].val != -1){if(!vis[t[i].val]){vis[t[i].val] = 1;//做标记++ans;}return;}query(i << 1,l,r);query(i << 1 | 1,l,r);
}int ask(int l,int r)
{memset(vis,0,sizeof(vis));ans = 0;vis[0] = 1;query(1,l,r);return ans;
}int main()
{   int T = read();while(T--){int m=init();   tot=0;//海报染成的颜色build(1,1,m);for(int i = 1;i <= n;i++)updata(1,a[i].l,a[i].r,++tot);printf("%d\n",ask(1,m));}return 0;
}

转载于:https://www.cnblogs.com/zhenglw/p/9507872.html

题解 UVA10587 【Mayor's posters】相关推荐

  1. POJ 2528 Mayor's posters(线段树)

    题目大意 贴海报.每张海报的高度都是一样的,唯独宽度不一样.每张海报只能占用整数倍的单位线段长度,贴了 n(n<=10000) 张海报之后,有几张能够看见(有一个角能看见这张海报也算被看见了)? ...

  2. poj 2528 Mayor's posters(线段树+离散化)

    1 /* 2 poj 2528 Mayor's posters 3 线段树 + 离散化 4 5 离散化的理解: 6 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用 ...

  3. 离散化/线段树 (POJ - 2528 Mayor's posters)

    Mayor's posters https://vjudge.net/problem/POJ-2528#author=szdytom 线段树 + 离散化 讲解:https://blog.csdn.ne ...

  4. poj 2528 Mayor's posters(线段树 离散化 区间更新 贴海报)

         这个题目本来对大神来说可能是水题, 对我就不行了,昨晚非折腾到下半夜一点 搞定, 并且可以总结出 ,只有把问题想清楚,或着看人家解题报告自己把问题和代码思路 搞清楚,才能谈的上调bug,否则 ...

  5. Mayor's posters POJ - 2528 (离散化+线段树)

    题意: 在1~10000000这个区间中读取n个海报的区间信息,后面的海报会覆 盖前面的海报,问最后能看到几张海报.(本题是一道bug题下面会提) 题目: The citizens of Byteto ...

  6. POJ Mayor's posters——线段树+离散化

    原文:http://blog.163.com/cuiqiongjie@126/blog/static/85642734201261151553308/ 大致题意: 有一面墙,被等分为1QW份,一份的宽 ...

  7. poj 2528 Mayor's posters (线段树+离散化)

    /*离散化+线段树由于 数据的输入最大是 10000000 ,直接用开数组肯点会超,所以要将起离散话,首先 ,我们存储输入的边,将其离散化,后面的就和一般的线段树一样可. */#include< ...

  8. POJ - 2528 Mayor's posters(线段数+离散化)

    题目链接:点击查看 题目大意:给定一个长度为1e7的墙,然后给出n张海报,每张海报都会占据墙上的一部分宽度,问按照给出的次序往墙上贴海报, 最后有几张海报能露出来(露出部分也算) 题目分析:线段树的区 ...

  9. POJ 2528 Mayor's posters (离散化和线段树使用)

    还是做了线段树的题目,玩了两天也要继续看看题目了.之前就有看离散化的概念,大家可以去百度百科一下,简单转载一个例子 离散化 的大概思路 : 比如说给你一组 数据 1 4 1000 100000, 如果 ...

最新文章

  1. MPB:西农焦硕组-​土壤微生物响应环境变化的系统发育保守性和环境阈值
  2. 用 mongodb + elasticsearch 实现中文检索
  3. network setup service启动后自动停止_一个简单的测试环境下的自动化部署方案
  4. 鸿蒙可胜安卓,【鸿蒙币谈】币圈投资中八大见顶信号,让你抓住最佳买卖机会!...
  5. 为ASP.NET MVC扩展异步Action功能(下)
  6. Codeforces Gym 101630J Travelling from Petersburg to Moscow (最短路)
  7. jooq中record_在Spring中使用jOOQ:CRUD
  8. Mac os安装SEAL
  9. 细数实现流水灯的三种代码形式
  10. 微信团购小程序怎么做?一般要多少钱?
  11. linux glibc升级
  12. 我家遥控器载波波形研究
  13. python漏洞扫描器编写,用Python编写Web漏洞检测工具
  14. Cpp--string常用函数用法总结
  15. ios 点生成线路 百度地图_iOS百度地图开发之路径规划
  16. 鸿蒙2.0 134个仓库扼要说明
  17. 2022最新综述 | 面向大规模场景的小目标检测:综述和 benchmark
  18. Among Us 限时免费下载
  19. 微信小程序导入微信聊天记录文件
  20. 大数据里面说的“移动计算比移动数据划算”究竟是什么意思

热门文章

  1. linux安装常用命令工具包wget,cmake等
  2. 及时输出_安全光幕没有输出信号怎么办?-意普ESPE
  3. STM32H743+CubeMX-ADC(16bit分辨率)+DMA采样三路模拟量,硬件过采样器实现1024倍过采样
  4. 计算机网络课程设计之基于 IP 多播的网络会议程序
  5. ThinkPHP5访问去除/public/index.php
  6. TCP/IP笔记-ARP协议包结构相关笔记
  7. Arduino笔记-有源蜂鸣器结合开关(多瑞咪发声)
  8. C++中多态的基本概念以及虚表的基本概念
  9. C++工作笔记-作用域的巧妙使用,释放堆区创建的资源
  10. Java高级语法笔记-多个异常处理