离散化这里有很多种方式

利用结构体记录最初的索引在按位置排序再记录排名即为离散的位置再按索引排回来

或者用数组记录排序后直接对原位置二分直接去找离散应在的位置

或者对数组排序后直接map<pos,rank> 记录位置

线段树离散化染色统计最后剩余多少种颜色

这里离散化要注意细节

给出附加两组数据先:

3 20
1 10
1 4
6 10
3 20
2 3
1 2
3 4

两组答案应该都为3

但这里如果直接计算的话第一组会计算得2

1-4和6-10 这里用到了所有的离散后的数据1-2和3-4本来1-4和6-10中间还有4-6的部分是1-10这张的但1-2被改为2,3-4被改为3没有1了所以输出为2

要是1-4后还有节点5的话就不会了至少节点5是1

所以这里可以采用给每个位置后增加一个位置0.5用来连接原先的所有的两个位置,这样连续的位置被染色后这个0.5的位置也被染掉了,之后被其它的修改两边会仍然保留这个点的颜色

所以这里最终离散也只是离散到点本来的海报还是连续的,除非添加题目中不会有的小数数据作为中间点,不然就会漏掉原来连续染色(贴海报)的某段

当然也可以通过像小Hi大神这么想问题才是看出问题的本质以及对本质的运用

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 1000000007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-9;
const int N = 1e6+5;
const int M = 21; int ans=0, cnt;
int n, m;
int c[N<<2];
int lan[N << 2];
int color[N << 2];
void down(int rt, int l, int r);
void up(int rt) {
if (c[rt << 1] > 0 && c[rt << 1 | 1] > 0)
{
if (c[rt << 1] == c[rt << 1 | 1])
c[rt] = c[rt << 1];
else
c[rt] = -1;
}
else {
c[rt] = -1;
}
}
void down(int rt,int l,int r) {
int m = (l + r) >> 1;
if (lan[rt]!=0) {
c[rt << 1] = c[rt];
c[rt << 1 | 1] = c[rt];
lan[rt << 1] = lan[rt];
lan[rt << 1 | 1] = lan[rt];
}
lan[rt] = 0;
}
void build(int l, int r, int rt) {
if (l == r) {
c[rt] = 0;
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
up(rt);
}
void update(int L,int R,int value,int l, int r, int rt) {
if (L<=l&&r<=R) {
c[rt] = value;
lan[rt] = 1;
return;
}
down(rt,l,r);
int m = (l + r) >> 1;
if (m >= L) {
update(L,R, value, lson);
}
if(m < R){
update(L,R, value, rson);
}
up(rt);
}
void query2(int L,int R,int l,int r,int rt) {
if (L <= l&&R >= r) {
if (c[rt] > 0) {
color[c[rt]]++;
return;
}
if (l == r)return;
}
down(rt, l, r);
int m = (l + r) >> 1;
if (m >= L) {
query2(L, R, lson);
}
if(m<R){
query2(L, R, rson);
}
return;
}
struct node {
int index;
double pos;
int rank;
}nd[N];
int cmp(node a, node b) {
return a.pos < b.pos;
}
int cmp2(node a, node b) {
return a.index < b.index;
} int main(){
memset(c, -1, sizeof c);
memset(lan, 0, sizeof lan);
int tlen;
scanf("%d%d", &m,&tlen);
cnt = 0;
for(int i=0;i<m;i++){
int op, l, r, value;
scanf("%d%d", &l, &r);
nd[cnt].index = i*2;
nd[cnt].pos = l;
cnt++;
nd[cnt].index = i*2+1;
nd[cnt].pos = r;
cnt++;
}
sort(nd, nd+cnt, cmp);
int tcnt = cnt;
for (int i = 0; i < tcnt; i++) {
nd[cnt].index = 999999;
nd[cnt++].pos = nd[i].pos + 0.5;
}
sort(nd, nd + cnt, cmp);
int rk = 1;
nd[0].rank = rk;
for (int i = 1; i < cnt; i++) {
if (nd[i].pos > nd[i - 1].pos)
nd[i].rank = ++rk;
else
nd[i].rank = rk;
}
sort(nd, nd + cnt, cmp2);
build(0, rk, 1);
for (int i = 0; i < m; i++) {
update(nd[i * 2].rank, nd[i * 2 + 1].rank, i+1, 1, rk, 1);
}
query2(1, rk, 1, rk, 1);
for (int i = 1; i <= m; i++)
if (color[i] != 0)
ans++; printf("%d\n", ans);
return 0;
}
在线段树的通常用法中,线段树的节点是有2种不同的意义的,一种是离散型的,比如在Hiho一下 第二十周中,一个节点虽然描述的是一个区间[3, 9],但是实际上这样一个区间是{3, 4, 5, 6, 7, 8, 9}这样的意义。而另一种就是连续型的,比如就在这一周的问题中,一个节点如果描述的是一个区间[3, 9],它就确确实实描述的是在数轴上从3这个标记到9这个标记的这一段。

那么有的小朋友可能就要问了,这两种不同的意义有什么区别呢?

在小Hi看来,其实只有这样的几个区别:1.叶子节点:在离散型中,叶子节点是[i, i],而连续性中是[i, i + 1];2.分解区间:在离散型中,一段区间是分解成为[l, m], [m + 1, r],而在连续型中,是分解成为[l, m], [m, r];3.其他所有类似的判定问题。

那么亲爱的小朋友们,你们懂了么?

这里注意到l=r-1之后就可以不处理了,不然不加条件或不另外加条件会无线循环的另外之前的m+1<=R也就是m<R这里因为连续了可以改为m<=R了

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
#define mod 1000000007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-9;
const int N = 1e6+5;
const int M = 21; int ans=0, cnt;
int n, m;
int c[N<<2];
int lan[N << 2];
int color[N << 2];
void down(int rt, int l, int r);
void up(int rt) {
if (c[rt << 1] > 0 && c[rt << 1 | 1] > 0)
{
if (c[rt << 1] == c[rt << 1 | 1])
c[rt] = c[rt << 1];
else
c[rt] = -1;
}
else {
c[rt] = -1;
}
}
void down(int rt,int l,int r) {
int m = (l + r) >> 1;
if (lan[rt]!=0) {
c[rt << 1] = c[rt];
c[rt << 1 | 1] = c[rt];
lan[rt << 1] = lan[rt];
lan[rt << 1 | 1] = lan[rt];
}
lan[rt] = 0;
}
void build(int l, int r, int rt) {
if (l == r-1) {
c[rt] = 0;
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
up(rt);
}
void update(int L,int R,int value,int l, int r, int rt) {
//if (r <= L||l>=R)return;
if (L<=l&&r<=R) {
c[rt] = value;
lan[rt] = 1;
return;
}
if (l == r - 1)return;
down(rt,l,r);
int m = (l + r) >> 1;
if (m >= L) {
update(L,R, value, lson);
}
if(m <= R){
update(L,R, value, rson);
}
up(rt);
}
void query2(int L,int R,int l,int r,int rt) {
//if (r <= L || l>=R)return;
if (L <= l&&R >= r) {
if (c[rt] > 0) {
color[c[rt]]++;
return;
}
}
if (l == r - 1)return;
down(rt, l, r);
int m = (l + r) >> 1;
if (m >= L) {
query2(L, R, lson);
}
if(m<=R){
query2(L, R, rson);
}
return;
}
struct node {
int index;
double pos;
int rank;
}nd[N];
int cmp(node a, node b) {
return a.pos < b.pos;
}
int cmp2(node a, node b) {
return a.index < b.index;
}
int a[N];
int b[N];
map<int, int> f; int main(){
memset(c, -1, sizeof c);
memset(lan, 0, sizeof lan);
int tlen;
scanf("%d%d", &m,&tlen);
cnt = 0;
for(int i=0;i<m;i++){
int op, l, r, value;
scanf("%d%d", &l, &r);
nd[cnt].index = i*2;
nd[cnt].pos = l;
cnt++;
nd[cnt].index = i*2+1;
nd[cnt].pos = r;
cnt++;
}
sort(nd, nd+cnt, cmp);
int rk = 1;
nd[0].rank = rk;
for (int i = 1; i < cnt; i++) {
if (nd[i].pos > nd[i - 1].pos)
nd[i].rank = ++rk;
else
nd[i].rank = rk;
}
sort(nd, nd + cnt, cmp2);
build(0, rk, 1);
for (int i = 0; i < m; i++) {
update(nd[i * 2].rank, nd[i * 2 + 1].rank, i+1, 1, rk, 1);
}
query2(1, rk, 1, rk, 1);
for (int i = 1; i <= m; i++)
if (color[i] != 0)
ans++; printf("%d\n", ans);
return 0;
}

Hihocoder 1079 离散化的更多相关文章

  1. hihoCoder - 1079 - 离散化 (线段树 + 离散化)

    #1079 : 离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho在回国之后,又一次过起了朝7晚5的学生生活.当然了.他们还是在一直学习着各种算法 ...

  2. hihoCoder #1079 : 离散化 (线段树,数据离散化)

    题意:有一块宣传栏,高一定,给出长度,再给出多张海报的张贴位置,问还能见到几张海报(哪怕有一点被看到)?假设海报的高于宣传栏同高. 思路:问题转成“给出x轴上长为L的一条线段,再用n条线段进行覆盖上去 ...

  3. poj 2528 Mayor's posters 线段树+离散化 || hihocode #1079 离散化

    Mayor's posters Description The citizens of Bytetown, AB, could not stand that the candidates in the ...

  4. hihoCoder#1079(线段树+坐标离散化)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学 ...

  5. hiho #1079 : 离散化

    描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报 ...

  6. hihoCoder:#1079(线段树+离散化)

    题目大意:给n个区间,有的区间可能覆盖掉其他区间,问没有完全被其他区间覆盖的区间有几个?区间依次给出,如果有两个区间完全一样,则视为后面的覆盖前面的. 题目分析:区间可能很长,所以要将其离散化.但离散 ...

  7. HihoCoder 1590 : 紧张的会议室(区间最大+离散化)

    时间限制:20000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi的公司最近员工增长迅速,同时大大小小的会议也越来越多:导致公司内的M间会议室非常紧张. 现在小Hi知道公司目前有N个 ...

  8. hihocoder-1079题解(线段树+离散化)

    一.题目链接 http://hihocoder.com/problemset/problem/1079 二.题意 给定一个长度为L的区间,给你n个子区间,没一个区间涂成一种颜色,问最后这个区间内有几种 ...

  9. [HIHO1079]离散化(线段树、染色)

    题目链接:http://hihocoder.com/problemset/problem/1079 MD坑爹,线段查询的时候左闭右开.插完挨个点找一遍扔set里,注意没染色的情况. #include ...

随机推荐

  1. Noip2016

    <这篇是以前的,不开新的了,借版面来换了个标题> 高二了 开学一周,每天被文化课作业碾压... 但是仍然阻挡不了想刷题的心情... 对付noip2016的几块:(有点少,以后补) 高精度( ...

  2. 版本管理之Git(二):Win7上Git安装及简单配置过程

    一.安装包 msysgit(Windows版本的Git) 下载地址:http://code.google.com/p/msysgit/downloads/list?q=full+installer+o ...

  3. CodeForces 519B A and B and Compilation Errors

    B. A and B and Compilation Errors time limit per test 2 seconds memory limit per test 256 megabytes ...

  4. 【Eclipse】 Eclipse 中JPEGEncodeParam 错误波浪线问题

    [异常信息] Description Resource Path Location Type Access restriction: The method encode(BufferedImage, ...

  5. 用maven配置springboot+freemarker

    1.创建项目 直接点下一步   原因: 不勾选 Create from archetype,是项目创建的骨架的时候,由于不知道什么原因就卡住了,一直在刷新 2.创建之后完成之后 添加依赖 <pa ...

  6. Win 10 文件浏览器无法打开

    今天遇到个很奇怪的问题,文件浏览器File Explorer无法正常显示,点击打开后任务栏上已经显示打开了,但是屏幕上却看不到任何窗口,开始以为机子中了恶意的木马,然后就疯狂的查毒,然而并没有解决问题 ...

  7. Odoo 8.0 new API 之Environment

    """ An environment wraps data for ORM records: - :attr:`cr`, the current database cur ...

  8. Struts2_ValueStack,OGNL详解(转)

    原文地址:http://blog.csdn.net/wyply115/article/details/8257140 一.OGNL表达式 1.ognl是struts2中使用的一种表达式语言,可用于js ...

  9. js 获取指定日期

    查询几天后的js代码,如果查询当天的日期 if($("input[name='startTime']").val()==""){ $("input[n ...

  10. localstorage 的属性改变问题

    localstorage 得到的是对象,我们打算改对象的某个属性的值,方法是 通过临时变量对象得到,改变临时变量,然后把临时变量给localstorage的方法 var localS  = windo ...