题目大意:给出一些海报和贴在墙上的区间。问这些海报依照顺序贴完之后,最后能后看到多少种海报。

思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化。

之后用线段树随便搞搞就能过。

关键是离散化的方法,这个题我时隔半年才A掉,之前一直就TTT,我还以为是线段树写挂了。

当我觉得我自己的水平这样的水线段树已经基本写不挂的时候又写了这个题,竟然还是T。

后来我对照别人的代码,才发现是我的离散化写渣了。

以下附AC代码(79ms),这个离散化写的比較优雅。时间也非常快,以后就这么写了。

CODE(POJ 79ms):

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 100010
#define LEFT (pos << 1)
#define RIGHT (pos << 1|1)
using namespace std; pair<int,int> interval[MAX];
pair<int,int *> src[MAX << 1]; int cases;
int tree[MAX << 2];
int intervals;
int cnt,t;
bool color[MAX]; inline void Initialize()
{
t = cnt = 0;
memset(color,false,sizeof(color));
memset(tree,0,sizeof(tree));
} inline void PushDown(int pos)
{
if(tree[pos]) {
tree[LEFT] = tree[pos];
tree[RIGHT] = tree[pos];
tree[pos] = 0;
}
} inline void Modify(int l,int r,int x,int y,int pos,int c)
{
if(l == x && y == r) {
tree[pos] = c;
return ;
}
PushDown(pos);
int mid = (l + r) >> 1;
if(y <= mid) Modify(l,mid,x,y,LEFT,c);
else if(x > mid) Modify(mid + 1,r,x,y,RIGHT,c);
else {
Modify(l,mid,x,mid,LEFT,c);
Modify(mid + 1,r,mid + 1,y,RIGHT,c);
}
} void GetAns(int l,int r,int pos)
{
if(tree[pos]) {
color[tree[pos]] = true;
return ;
}
if(l == r) return ;
int mid = (l + r) >> 1;
GetAns(l,mid,LEFT);
GetAns(mid + 1,r,RIGHT);
} int main()
{
for(cin >> cases; cases; --cases) {
scanf("%d",&intervals);
Initialize();
for(int i = 1; i <= intervals; ++i) {
scanf("%d%d",&interval[i].first,&interval[i].second);
src[++cnt] = make_pair(interval[i].first,&interval[i].first);
src[++cnt] = make_pair(interval[i].second,&interval[i].second);
}
sort(src + 1,src + cnt + 1);
for(int i = 1; i <= cnt; ++i)
{
if(src[i].first != src[i - 1].first) ++t;
*src[i].second = t;
}
for(int i = 1; i <= intervals; ++i)
Modify(1,cnt,interval[i].first,interval[i].second,1,i);
GetAns(1,cnt,1);
int ans = 0;
for(int i = 1; i <= intervals; ++i)
ans += color[i];
printf("%d\n",ans);
}
return 0;
}

为了警醒后人,也为了警醒自己(以后再也不这么写离散化了)。我将我T的离散化代码也发上来,好孩子千万不要学习。

CODE(POJ TLE):

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
#define LEFT (pos << 1)
#define RIGHT (pos << 1|1)
using namespace std; pair<int,int> interval[MAX];
map<int,int> G; int cases;
int tree[MAX << 2];
int intervals,src[MAX << 1];
int cnt,t;
bool color[MAX]; inline void Initialize()
{
G.clear();
t = cnt = 0;
memset(color,false,sizeof(color));
memset(tree,0,sizeof(tree));
} inline void PushDown(int pos)
{
if(tree[pos]) {
tree[LEFT] = tree[pos];
tree[RIGHT] = tree[pos];
tree[pos] = 0;
}
} inline void Modify(int l,int r,int x,int y,int pos,int c)
{
if(l == x && y == r) {
tree[pos] = c;
return ;
}
PushDown(pos);
int mid = (l + r) >> 1;
if(y <= mid) Modify(l,mid,x,y,LEFT,c);
else if(x > mid) Modify(mid + 1,r,x,y,RIGHT,c);
else {
Modify(l,mid,x,mid,LEFT,c);
Modify(mid + 1,r,mid + 1,y,RIGHT,c);
}
} void GetAns(int l,int r,int pos)
{
if(tree[pos]) {
color[tree[pos]] = true;
return ;
}
if(l == r) return ;
int mid = (l + r) >> 1;
GetAns(l,mid,LEFT);
GetAns(mid + 1,r,RIGHT);
} int main()
{
for(cin >> cases; cases; --cases) {
scanf("%d",&intervals);
Initialize();
for(int i = 1; i <= intervals; ++i) {
scanf("%d%d",&interval[i].first,&interval[i].second);
src[++cnt] = interval[i].first;
src[++cnt] = interval[i].second;
}
sort(src + 1,src + cnt + 1);
G[src[1]] = ++t;
for(int i = 2; i <= cnt; ++i)
if(src[i] != src[i - 1])
G[src[i]] = ++t;
for(int i = 1; i <= intervals; ++i)
Modify(1,cnt,G[interval[i].first],G[interval[i].second],1,i);
GetAns(1,cnt,1);
int ans = 0;
for(int i = 1; i <= intervals; ++i)
ans += color[i];
printf("%d\n",ans);
}
return 0;
}

后来我和小伙伴门一起研究了这样的离散化方法,正常来说是不会T的,尽管多带了一个log。可是这个题是多组数据啊。坑啊,每一组数据就要clear一下map。据老师说map的clear是一个一个删的。。

。于是机制的我就每次new一个map,这样就不用clear了。结果交上去果然A了。

CODE(POJ 344ms):

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
#define LEFT (pos << 1)
#define RIGHT (pos << 1|1)
using namespace std; pair<int,int> interval[MAX];
map<int,int> *G; int cases;
int tree[MAX << 2];
int intervals,src[MAX << 1];
int cnt,t;
bool color[MAX]; inline void Initialize()
{
G = new map<int,int>;
t = cnt = 0;
memset(color,false,sizeof(color));
memset(tree,0,sizeof(tree));
} inline void PushDown(int pos)
{
if(tree[pos]) {
tree[LEFT] = tree[pos];
tree[RIGHT] = tree[pos];
tree[pos] = 0;
}
} inline void Modify(int l,int r,int x,int y,int pos,int c)
{
if(l == x && y == r) {
tree[pos] = c;
return ;
}
PushDown(pos);
int mid = (l + r) >> 1;
if(y <= mid) Modify(l,mid,x,y,LEFT,c);
else if(x > mid) Modify(mid + 1,r,x,y,RIGHT,c);
else {
Modify(l,mid,x,mid,LEFT,c);
Modify(mid + 1,r,mid + 1,y,RIGHT,c);
}
} void GetAns(int l,int r,int pos)
{
if(tree[pos]) {
color[tree[pos]] = true;
return ;
}
if(l == r) return ;
int mid = (l + r) >> 1;
GetAns(l,mid,LEFT);
GetAns(mid + 1,r,RIGHT);
} int main()
{
for(cin >> cases; cases; --cases) {
scanf("%d",&intervals);
Initialize();
for(int i = 1; i <= intervals; ++i) {
scanf("%d%d",&interval[i].first,&interval[i].second);
src[++cnt] = interval[i].first;
src[++cnt] = interval[i].second;
}
sort(src + 1,src + cnt + 1);
(*G)[src[1]] = ++t;
for(int i = 2; i <= cnt; ++i)
if(src[i] != src[i - 1])
(*G)[src[i]] = ++t;
for(int i = 1; i <= intervals; ++i)
Modify(1,cnt,(*G)[interval[i].first],(*G)[interval[i].second],1,i);
GetAns(1,cnt,1);
int ans = 0;
for(int i = 1; i <= intervals; ++i)
ans += color[i];
printf("%d\n",ans);
}
return 0;
}

POJ 2528 Mayor&#39;s posters 离散化+线段树的更多相关文章

  1. poj 2528 Mayor&#39;s posters 【线段树 + 离散化】

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

  2. POJ 2528 Mayor&#39;s posters 离散化和线段树题解

    本题就是要往墙上贴海报,问最后有多少可见的海报. 事实上本题的难点并非线段树,而是离散化. 由于数据非常大,直接按原始数据计算那么就会爆内存和时间的. 故此须要把数据离散化. 比方有海报1 6   7 ...

  3. poj2528 Mayor&#39;s posters(线段树,离散化)

    离散化的思想: 对于这样的数据 (3,10000). (9,1000000). (5.100000), (1,1000). (7,1000000) 我们能够将其处理为 (2,7). (5,9). (3 ...

  4. poj 2528 Mayor&#39;s posters

    这个题意是市长竞选,然后每一个人都能够贴广告牌.能够覆盖别人的看最后剩几个广告牌 这题目想了两个多小时,最后忍不住看了一下题解. 发现仅仅是简单地hash  和线段树成段更新 由于有10000个人竞选 ...

  5. 【hdu】Mayor&#39;s posters(线段树区间问题)

    须要离散化处理,线段树的区间改动问题. 须要注意的就是离散化的时候,由于给的数字是一段单位长度,所以须要特殊处理(由于线段的覆盖和点的覆盖是不一样的) 比方:(1,10)(1,4) (6,10) 离散 ...

  6. 线段树区间更新,区间统计+离散化 POJ 2528 Mayor&#39;s posters

    题意:有一个非常长的板子(10000000长),在上面贴n(n<=10000)张海报.问最后从外面能看到几张不同的海报. 由于板子有10000000长,直接建树肯定会爆,所以须要离散化处理,对于 ...

  7. POJ2528 Mayor&#39;s posters 【线段树】+【成段更新】+【离散化】

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

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

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

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

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

随机推荐

  1. luogu P3368 【模板】树状数组 2

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  2. 【枚举】bzoj1709 [Usaco2007 Oct]Super Paintball超级弹珠

    由于子弹的轨迹是可逆的,因此我们可以枚举所有敌人的位置,然后统计他们能打到的位置,这些位置也就是能打到他们的位置咯. O(n*k). #include<cstdio> using name ...

  3. C# 二维码扫描

    Zint类用于产生二维码.https://sourceforge.net/projects/zint/ Zxing类用于读取二维码. https://github.com/zxing/zxing AF ...

  4. java static代码段

    1)java中还有个static代码块的形式,形式为 static {……}.static代码块是类定义的一部分,仅仅在类被初次加载的时候被调用一次,之后再调用不会再加载.那么类什么时候首次被加载呢? ...

  5. 《深入理解Spark-核心思想与源码分析》(三)第三章SparkContext的初始化

    3.1 SparkContext概述 SparkConf负责配置参数,主要通过ConcurrentHaspMap来维护各种Spark的配置属性. class SparkConf(loadDefault ...

  6. Missing iOS Distribution signing identity解决方案

    相信很多朋友跟我遇到相同的问题,之前iOS发布打包的证书没问题,现在莫名其妙的总是打包失败,并且报如下错误 第一反应,是不是证书被别人搞乱了.于是去Developer Member Center,把所 ...

  7. [Bug]CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temp

    win7中安装asp.net的问题 编译器错误信息: CS0016: 未能写入输出文件问题解决办法 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地 ...

  8. Python数据整合与数据准备-BigGorilla实例应用

    参考文档:http://www.biggorilla.org/walkt/ 一.BigGorilla应用主要步骤 如下图: 二.实例应用 1.数据获取 urllib是非常受欢迎的用于在网络上读取数据的 ...

  9. Centos下输入法全角半角转换

    写个文档 ,发现输入法的设置框没有了,打出来的字全是全角,找了半天终于发现在设置的快捷键. 废话少说,Centos的全角半角转换快捷键是shift+space. 中英文标点的转换快捷键 ctrl+.

  10. golang中的那些坑之迭代器中的指针使用

    今天在编写代码的时候,遇到了一个莫名其妙的错误,debug了半天,发现这是一个非常典型且易犯的错误.记之 示例代码: package main import "fmt" type ...