当前位置: 首页 > news >正文

POJ 2528(线段树+离散化)

题意:n(n<=10000)个人依次贴海报, 给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。

求出最后还能看见多少张海报。(题意是我抄的...)

思路:

能够想到用线段树去进行区间更新,求最终的更新结果。但发现给的数据会得到1000万,所以普通的线段树是开不了的,但是发现n的范围为1万,可以在这上面做点文章,所以可以对这给定的n个区间进行离散化。

普通离散化的具体步骤为:对所有输入的数排序,然后进行去重,然后将数映射到1~n。

但是普通离散化在本题中是不可行的,我们注意到,每个数字其实表示的是一个单位长度(一个点也是一段),举个栗子:

1-10 1-4 6-10  直接进行算得到的ans是3

进行离散化:X[1] = 1, X[2] = 4, X[3] = 6, X[4] = 10

1-4 1-2 3-4    计算得到ans为2,结果错误!

怎么解决呢?如果相邻数字间距大于1的话, 在其中加上任意一个中间数字, 比如上面例子会加成[1, 3, 4, 5, 6, 7, 10], 然后再做线段树就ok,这样做可以防止丢失单点的成段效果。


具体代码实现如下:

#include <algorithm>
#include <iostream>
#include <string.h>
#include <cstdio>
#include <set>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 10005;
int col[maxn<<4], lazy[maxn<<4];
int inp[maxn][2], chg[maxn<<2];
set<int> hash;	//记录访问过与否 
void pushDown(int rt)
{
	if(lazy[rt])
	{
		lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
		col[rt<<1] = col[rt<<1|1] = lazy[rt];
		lazy[rt] = 0;
	}
}
void build(int l, int r, int rt)
{
	lazy[rt] = 0;
	col[rt] = 0;
	if(l == r) return;
	int m = (l+r) >> 1;
	build(lson);
	build(rson);
}
void update(int k, int L, int R, int l, int r, int rt)
{
	if(L <= l && R >= r)
	{
		col[rt] = k;
		lazy[rt] = k;
		return;
	}
	pushDown(rt);
	int m = (l+r) >> 1;
	if(L <= m) update(k, L, R, lson);
	if(R > m) update(k, L, R, rson); 
}
int query(int l, int r, int rt)
{
	if(l == r) 
	{
		if(col[rt] && !hash.count(col[rt]))
		{
			hash.insert(col[rt]);
			return 1;
		}
		return 0;
	}
	pushDown(rt);
	int m = (l+r) >> 1;
	return query(lson) + query(rson);
}
int main()
{
	int t, n, l, r, cnt;
	scanf("%d", &t);
	for(int i = 1; i <= t; ++i)
	{
		hash.clear(); cnt = 0;
		scanf("%d", &n);
		for(int j = 1; j <= n; ++j)
		{
			scanf("%d %d", &inp[j][0], &inp[j][1]);
			chg[cnt++] = inp[j][0];
			chg[cnt++] = inp[j][1];
		}
		sort(chg, chg+cnt);
		cnt = unique(chg, chg+cnt) - chg;
		int tmp = cnt;
		for(int j = 1; j < tmp; ++j)
		{
			if(chg[j] - chg[j-1] > 1) chg[cnt++] = chg[j-1]+1;
		}
		sort(chg, chg+cnt);
		build(1, cnt, 1);
		for(int j = 1; j <= n; ++j)
		{
			int a = lower_bound(chg, chg+cnt, inp[j][0]) - chg;
			int b = lower_bound(chg, chg+cnt, inp[j][1]) - chg;
			++a, ++b;
			update(j, a, b, 1, cnt, 1);
		}
		printf("%d\n", query(1, cnt, 1));
	}
	return 0;
}


在这儿再补充一下知识点。

1.unique函数

unique()函数是STL中得一个去重函数,在头文件<algorithm>中,unique的功能是去除相邻的重复元素(只保留一个),还有一个容易忽视的特性是它并不真正把重复的元素删除。
unique(num, num+n)返回的是num去重后的尾地址,之所以说比是真正把重复的元素删除,其实是,该函数把重复的元素移到后面去了,依然保存到了原数组中,然后返回去重后的最后一个元素的下一地址。因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。

2.离散化主要代码

sort(num, num+cnt);//排序 
cnt = unique(num, num+cnt) - num;//去重 
for(int i = 1; i <= m; ++i)
{
	int k = lower_bound(num, num+cnt, input[i]) - num;
	//取对应的值在数组中的位置以对应离散值 
	++k;
	//通常使k++,另第一个离散值为1
	//同理也可通过离散值在数组中找到原数值 
}

继续加油~

相关文章:

  • hadoop问题与解决办法
  • HDU 4725(最短路之建图难点)
  • QDU首届易途杯大赛-kk与cillyb的荣誉之战
  • Visual Studio 有哪些好用的插件?
  • QDU首届易途杯大赛-ycb老师与一道简单的物理题
  • SqlTest(2013-07-10)
  • 蓝桥杯-K倍区间(前缀和) 分巧克力(二分)
  • Linux下MySQL5.6源码安装
  • HDU-1024 Max Sum Plus Plus(DP)
  • C#开发微信门户及应用(27)-公众号模板消息管理
  • CodeForces 628D(数位DP)
  • 多重背包--二进制优化
  • JS高级程序设计2nd部分知识要点2
  • HDU-4549(矩阵快速幂+欧拉定理)
  • xcode Aborting commit: '~/Pods' remains in tree-conflict 错误的解决办法
  • 230. Kth Smallest Element in a BST
  • 4个实用的微服务测试策略
  • centos安装java运行环境jdk+tomcat
  • interface和setter,getter
  • Java的Interrupt与线程中断
  • JS字符串转数字方法总结
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Map集合、散列表、红黑树介绍
  • scrapy学习之路4(itemloder的使用)
  • Tornado学习笔记(1)
  • VUE es6技巧写法(持续更新中~~~)
  • 计算机常识 - 收藏集 - 掘金
  • 前端临床手札——文件上传
  • 我建了一个叫Hello World的项目
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​比特币大跌的 2 个原因
  • #在 README.md 中生成项目目录结构
  • (2)Java 简介
  • (26)4.7 字符函数和字符串函数
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Matlab)使用竞争神经网络实现数据聚类
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (算法)前K大的和
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)linux 命令大全
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • *Django中的Ajax 纯js的书写样式1
  • .net core Swagger 过滤部分Api
  • .NET Core WebAPI中封装Swagger配置
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net mvc部分视图
  • .net和jar包windows服务部署
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • .net下简单快捷的数值高低位切换
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • /bin/bash^M: bad interpreter: No such file ordirectory