题目链接:

题意:给定一些高度都相同的海报去贴,问最后能看见几张海报

The picture below illustrates the case of the sample input.

{ 8,9,10}那张被覆盖看不到,

分析:看了大神们的博客大神是一看就是线段树,可是我都知道是线段树了也不知道怎么做,真是弱的一逼;

线段树分析就是对于每一个海报所在的区间设置一个不同的数字,然后就统计有几个不同的数字即所求解,就是线段树区间更改

技巧:离散化

如果按照这个墙的宽度来设置线段树的话,很大,内存会超。考虑到海报的个数不会很多,所以根据海报的区间的两个端点来进行离散处理,

拿例子来说,{1,4} {2,6} {8,10} {3,4} {7,10} ,所以需要的点为 1, 2, 3, 4, 6, 7, 8 ,10,令x[1] = 1, x[2] = 2,x[3] = 3,x[4] = 4,x[5] = 6,x[6] = 7,x[7] = 8, x[8] = 10,就将原来大的 【 1,10】区间变成了【1,8】这就是离散化

还有一个bug,如果这组样例: {1,10} {1,3} {5,10} 就离散成了 x[1] = 1, x[2] = 3, x[3] = 5, x[4] = 10,

第一张海报时候{1,10},对于离散化后的处理时,{1,4}

第二张{1,3}, 对于离散化后的就是{1,2}

第三张{5,10},对于离散化后的就是{3,4}

对于离散化后的来统计,最后结果是2,而实际确实3,原因就是 3到5之间有4而离散化之后就把4给去掉了,这就是一个bug,处理方法就是把相邻的两个数如果差大于1就在添加一个数

 #include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max = ; //根据海报的个数来设置数组
struct node
{
int l,r;
int cover; //海报的编号
int tag; //懒惰标志
};
node tree[Max * ];
int t[ * Max + ],cnt,res[Max * + ];
int a[Max + ],b[Max + ];
void buildTree(int left, int right, int k)
{
tree[k].l = left;
tree[k].r = right;
tree[k].cover = ;
tree[k].tag = -;
if(left == right)
return;
int mid = (left + right) / ;
buildTree(left, mid, k * );
buildTree(mid + , right, k * + );
}
int Find(int l, int r, int key, int temp[])
{
while(r >= l)
{
int mid = (l + r) / ;
if(temp[mid] == key)
return mid;
else if(temp[mid] > key)
{
r = mid - ;
}
else
{
l = mid + ;
}
}
return -;
}
void upDate(int left, int right, int k, int num)
{
if(tree[k].l == left && tree[k].r == right)
{
tree[k].cover = num;
tree[k].tag = num;
return;
}
if(tree[k].tag != -)
{
tree[k * ].tag = tree[k * + ].tag = tree[k].tag;
tree[k * ].cover = tree[k * + ].cover = tree[k].tag;
tree[k].tag = -;
}
int mid = (tree[k].l + tree[k].r) / ;
if(right <= mid)
{
upDate(left, right, k * , num);
}
else if(mid < left)
{
upDate(left, right, k * + , num);
}
else
{
upDate(left, mid, k * , num);
upDate(mid + , right, k * + , num);
}
}
void Search(int k)
{
if(tree[k].tag != -)
{
tree[k].cover = tree[k].tag;
tree[k * ].tag = tree[k * + ].tag = tree[k].tag;
tree[k * ].cover = tree[k * + ].cover = tree[k].tag;
tree[k].tag = -;
} if(tree[k].l == tree[k].r)
{
res[ tree[k].cover ] = ; // 看看每一个点的海报编号
return;
}
Search(k * );
Search(k * + );
}
int main()
{
int test,n;
scanf("%d", &test);
while(test--)
{
scanf("%d", &n);
cnt = ;
for(int i = ; i <= n; i++)
{
scanf("%d%d", &a[i], &b[i]);
t[ cnt++ ] = a[i];
t[ cnt++ ] = b[i]; //将所有的端点都放入t中
}
sort(t, t + cnt);
int cnt1 = ;
for(int i = ; i < cnt; i++)
{
if(t[i] != t[i - ]) //去掉相同的
t[ cnt1++ ] = t[i];
}
for(int i = cnt1 - ; i > ; i--)
{
if(t[i] - t[i - ] > ) //如果相邻数差值大于1,就则加一个数
t[ cnt1++ ] = t[i - ] + ;
}
sort(t, t + cnt1); //加完之后排序,此时已经离散完毕
for(int i = cnt1; i > ; i--)
t[i] = t[i - ];
//使区间为1到cnt1,好处理
buildTree(, cnt1, ); for(int i = ; i <= n; i++)
{
int left = Find(, cnt1, a[i], t); //二分查找出每个区间的端点在离散化后的数组中的位置
int right = Find(, cnt1, b[i], t);
upDate(left, right, , i); //更新,设置覆盖位为 i
}
memset(res, , sizeof(res));
Search(); //从根开始查找
int ans = ;
for(int i = ; i <= n; i++)
if(res[i])
ans++;
printf("%d\n", ans);
}
return ;
}

POJ2528Mayor's posters(离散化 + 线段树)的更多相关文章

  1. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

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

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54067   Accepted: 15713 ...

  3. POJ 2528 Mayor&#39;s posters 离散化+线段树

    题目大意:给出一些海报和贴在墙上的区间.问这些海报依照顺序贴完之后,最后能后看到多少种海报. 思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化. 之后用线段树随便搞搞就能过. 关键 ...

  4. 南阳理工 题目9:posters(离散化+线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

  5. Mayor's posters (离散化线段树+对lazy的理解)

    题目 题意: n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围 li,ri(1<=li<=ri<=10000000) .求出最后还能看见多少张海报. 思路: 由于 ...

  6. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  7. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

  8. 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树

    [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...

  9. 【bzoj4636】蒟蒻的数列 离散化+线段树

    原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...

  10. 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers

    题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...

随机推荐

  1. (十一)外观模式详解(Service第三者插足,让action与dao分手)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...

  2. Linux中sudo配置

    Linux下的sudo及其配置文件/etc/sudoers的详细配置. 1.sudo介绍 sudo是linux下常用的允许普通用户使用超级用户权限的工具,允许系统管理员让普通用户执行一些或者全部的ro ...

  3. php 实现创建文件并追加数据

    最近因为后台有其他事情忙,所以我最近又开始学习php的内容了. (不过话说回来从客户端写到后台的感觉还是很爽的,嘿嘿) 需求是这样:从前台发来一些信息,存成文本文档,以后再统一处理(比如,存入用户账户 ...

  4. 给li设置float浮动属性之后,无法撑开外层ul的问题。(原址:http://www.cnblogs.com/cielzhao/p/5781462.html)

    最近在项目中有好几次遇到这个问题,感觉是浮动引起的,虽然用<div style="clear:both"></div>解决了,但自己不是特别明白,又在网上查 ...

  5. Linux System and Performance Monitoring

    写在前面:本文是对OSCon09的<Linux System and Performance Monitoring>一文的学习笔记,主要内容是总结了其中的要点,以及加上了笔者自己的一些理解 ...

  6. springMVC+mybatis 增删该操作后判断影响行数一直返回-2147482646

    MyBatis发现更新和插入返回值一直为"-2147482646"的错误是由defaultExecutorType设置引起的,如果设置为BATCH,更新返回值就会丢失.mybati ...

  7. python 登陆接口

    #!/usr/bin/env pythonimport sysname = ''pw=''name_num = 0pw_num = 0#black_list = []with open('a.txt' ...

  8. 使用HTML5新特性Mutation Observer实现编辑器的撤销和撤销回退操作

     MutationObserver介绍 MutationObserver给开发者们提供了一种能在某个范围内的DOM树发生变化时作出适当反应的能力.该API设计用来替换掉在DOM3事件规范中引入的Mut ...

  9. lucene-查询query->WildcardQuery使用通配符搜索

    Lucene也提供了通配符的查询,这就是WildcardQuery. package ch11; import org.apache.lucene.analysis.standard.Standard ...

  10. Spring注解@PostConstruct与@PreDestroy

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二 ...