区间更新与单点更新最大的不同就在于Lazy思想:

http://blog.sina.com.cn/s/blog_a2dce6b30101l8bi.html

可以看这篇文章,讲得比较清楚

在具体使用上,因为是成段更新,目标区间内所有区间都需要更新,所以update时可以专门去找区间,不用一个个找点。所以可以不用node保存每个点左右范围,用a[]保存值,col[]保存标记反而比较方便

区间替换和区间增减在我的http://www.cnblogs.com/qlky/p/5690265.html中都写了,这里讲一下离散化:

离散化就是有时n个点的数据范围过大,或者过于分散。我们将节点映射到1-n中可以简化问题。基本过程如下:

  • 记录每个点的左端和右端,全部保存到一个数组a中并排序
  • 节点去重
  • 如果两个节点间距离大于1,添加一个中间节点
  • 再次对a排序
  • 在a中二分搜索原来每个点的左右端,将索引值保存在线段树中

示例代码:

sf("%d",&n);
int cnt = ,len = ;
for(i=;i<=n;i++)//记录头尾
{
sf("%d %d",&s1[i],&s2[i]);
a[++cnt] = s1[i];
a[++cnt] = s2[i];
}
sort(a+,a++cnt); for(i=;i<=cnt;i++)//去重
{
if(a[i]!=a[i-]) a[++len] = a[i];
} for(i=len;i>;i--)//添加中间值
{
if(a[i]-a[i-]>) a[++len] = a[i]-;
}
sort(a+,a++len); for(i=;i<=n;i++)
{
int l = BSearch(,len,s1[i]);
int r = BSearch(,len,s2[i]);
update(i,l,r,,len,);
}

以poj 2528为例:

http://blog.csdn.net/non_cease/article/details/7383736

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

求出最后还能看见多少张海报。

输入:

1
5
1 4
2 6
8 10
3 4
7 10

解法:离散化,如下面的例子(题目的样例),因为单位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~8的墙上(用线段树),最后统计不同颜色的段数。

但是只是这样简单的离散化是错误的,

如三张海报为:1~10 1~4 6~10

离散化时 X[ 1 ] = 1, X[ 2 ] = 4, X[ 3 ] = 6, X[ 4 ] = 10
第一张海报时:墙的1~4被染为1;
第二张海报时:墙的1~2被染为2,3~4仍为1;
第三张海报时:墙的3~4被染为3,1~2仍为2。
最终,第一张海报就显示被完全覆盖了,于是输出2,但实际上明显不是这样,正确输出为3。

新的离散方法为:在相差大于1的数间加一个数,例如在上面1 4 6 10中间加5(算法中实际上1,4之间,6,10之间都新增了数的)

X[ 1 ] = 1, X[ 2 ] = 4, X[ 3 ] = 5, X[ 4 ] = 6, X[ 5 ] = 10

这样之后,第一次是1~5被染成1;第二次1~2被染成2;第三次4~5被染成3

最终,1~2为2,3为1,4~5为3,于是输出正确结果3。

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 10000 + 5
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f int n,m; int a[MAXN<<],col[MAXN<<],ans; int s1[MAXN],s2[MAXN]; bool hh[MAXN]; void PushDown(int rt)
{
if(col[rt] != -)
{
col[rt<<] = col[rt<<|] = col[rt];
col[rt] = -;
}
} void update(int val,int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R)
{
col[rt] = val;
return;
}
PushDown(rt);
int mid = (l + r)>>;
if (L <= mid)
{
update(val,L,R,l,mid,rt<<);
}
if(R > mid)
{
update(val,L,R,mid+,r,rt<<|);
}
} void query(int l,int r,int rt)
{
if(l==r)
{
if(!hh[col[rt]])
{
ans++;
hh[col[rt]] = true;
}
return;
}
PushDown(rt);
int mid = (l + r)>>;
query(l,mid,rt<<);
query(mid+,r,rt<<|);
} int BSearch(int lo, int hi, int v)
{
int mid;
while (lo <= hi)
{
mid = (lo + hi) >> ;
if (a[mid] == v) return mid;
else if (a[mid] > v) hi = mid - ;
else lo = mid + ;
}
return -;
} int main()
{
int t,i,kase=;
sf("%d",&t);
while(t--)
{
mem(col,-);
mem(a,);
mem(hh,false);
sf("%d",&n);
int cnt = ,len = ;
for(i=;i<=n;i++)//????
{
sf("%d %d",&s1[i],&s2[i]);
a[++cnt] = s1[i];
a[++cnt] = s2[i];
}
sort(a+,a++cnt); for(i=;i<=cnt;i++)//??
{
if(a[i]!=a[i-]) a[++len] = a[i];
} for(i=len;i>;i--)//?????
{
if(a[i]-a[i-]>) a[++len] = a[i]-;
}
sort(a+,a++len); for(i=;i<=n;i++)
{
int l = BSearch(,len,s1[i]);
int r = BSearch(,len,s2[i]);
update(i,l,r,,len,);
}
ans = ;
query(,len,);
pf("%d\n",ans);
}
return ;
}

ACM-线段树区间更新+离散化的更多相关文章

  1. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  2. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

  3. POJ2528:Mayor's posters(线段树区间更新+离散化)

    Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...

  4. POJ-2528 Mayor's posters(线段树区间更新+离散化)

    http://poj.org/problem?id=2528 https://www.luogu.org/problem/UVA10587 Description The citizens of By ...

  5. POJ2528 Mayor's posters(线段树&区间更新+离散化)题解

    题意:给一个区间,表示这个区间贴了一张海报,后贴的会覆盖前面的,问最后能看到几张海报. 思路: 之前就不会离散化,先讲一下离散化:这里离散化的原理是:先把每个端点值都放到一个数组中并除重+排序,我们就 ...

  6. POJ 2528 Mayor's posters(线段树/区间更新 离散化)

    题目链接: 传送门 Mayor's posters Time Limit: 1000MS     Memory Limit: 65536K Description The citizens of By ...

  7. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

  8. POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】

    任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  9. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  10. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

随机推荐

  1. SVN Unable to connect to a repository at URL 不知道这样的主机: 问题解决

    工具是eclipse Maven ,搭建好项目的框架后上传SVN出现如下错误: 不知道这样的主机.  svn: Unable to connect to a repository at URL 'ht ...

  2. Android Studio for windows环境搭建

    Android Studio环境搭建 个人博客 欢迎大家多多关注该独立博客:   csdn博客  一直想把自己的经验分享出来,记得上次写博客还是ok6410的笔记,感觉时代久远啊.记得那个时候我还一心 ...

  3. location的属性

    http://localhost:8080/?a=b#/login location.host "localhost:8080" location.port 8080 locati ...

  4. 使用原生实现jquery中的css方法

    由于jquery放在mobile页面上,有时候还是显得有点大,所以今天尝试使用原生来开发,但是习惯了jquery之后,转用原生开发之后,发现原生中,找不到可以替代jquery的css方法,于是对原生的 ...

  5. [jvm]垃圾回收与内存分配策略

    一.垃圾回收算法 概述 JVM中,当创建的对象不再被使用的时候,此时我们认为他是无用的“垃圾”:在现代主流的商用jvm中,都是通过可达性分析来判断对象是否存活的.这个算法的基本思想是通过一系列“GCR ...

  6. SQL里的real类型和tinyint类型在C#里分别对应类型

  7. PHP脚本占用内存太多,解决方案

    Fatal Error: Allowed memory size of xxxxxx bytes exhausted 今天遇到服务器很多自动任务的php脚本占用服务内存过多,并且程序不在运行了. 解决 ...

  8. 洛谷 P4001 [ICPC-Beijing 2006]狼抓兔子

    题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  9. ansible基本模块-copy

    ansible   XXX   -m copy  -a  “src=XXX  dest=XXX  owner=root  group=root  mode=0755”

  10. zTree学习笔记

    一.zTree的下载 官网:http://www.treejs.cn/v3/main.php#_zTreeInfo 解压后的目录结构为: 二.zTree入门案例 2.1 在页面中引入相关文件 要使用z ...