ACM-线段树区间更新+离散化
区间更新与单点更新最大的不同就在于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-线段树区间更新+离散化的更多相关文章
- POJ-2528 Mayor's posters (线段树区间更新+离散化)
题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
- POJ2528:Mayor's posters(线段树区间更新+离散化)
Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...
- POJ-2528 Mayor's posters(线段树区间更新+离散化)
http://poj.org/problem?id=2528 https://www.luogu.org/problem/UVA10587 Description The citizens of By ...
- POJ2528 Mayor's posters(线段树&区间更新+离散化)题解
题意:给一个区间,表示这个区间贴了一张海报,后贴的会覆盖前面的,问最后能看到几张海报. 思路: 之前就不会离散化,先讲一下离散化:这里离散化的原理是:先把每个端点值都放到一个数组中并除重+排序,我们就 ...
- POJ 2528 Mayor's posters(线段树/区间更新 离散化)
题目链接: 传送门 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Description The citizens of By ...
- POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)
POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...
- POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total S ...
- HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
随机推荐
- [AGC006] D - Median Pyramid Hard 二分
Description 现在有一个NN层的方块金字塔,从最顶层到最底层分别标号为1...N1...N. 第ii层恰好有2i−12i−1个方块,且每一层的中心都是对齐的. 这是一个N=4N=4的 ...
- bzoj2564: 集合的面积(闵可夫斯基和 凸包)
题面 传送门 题解 花了一个下午的时间调出了一个稍微能看的板子--没办法网上的板子和咱的不太兼容-- 首先有一个叫做闵可夫斯基和的东西,就是给你两个点集\(A,B\),要你求一个点集\(C=\{x+y ...
- 自旋锁Spin lock与互斥锁Mutex的区别
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- 用IDM下载博客图片
前言 写博客的人一定都会有一个图床,将图片存在那里.发现自己以前没有注意图片来源问题,随手就贴在博客上面了.现在有不少图片都挂了,换句话来说有可能自己目前用的图床不提供服务了,那所有的图片都有可能丢失 ...
- JAVA通过网站域名URL获取该网站的源码(2018
import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnect ...
- ORACLE的查询语句
oracle的select查询语句(DQL): 语法: select //查询动作关键字 [distinct|all] //描述列表字段中的数据是否去除记录 select_list //需要查询的字段 ...
- Echarts图表横坐标显示不全
xAxis: { "axisLabel":{ //加上这个强制显示 interval: 0 }, type: 'category', data: self[theDataKey]. ...
- C# B站的弹幕提取
要知道B站的弹幕位置 如果只考虑视频,B站的链接格式为:https://www.bilibili.com/video/av34042815.把av后面的数字看做是唯一标记即可. 既然能够把弹幕加载出来 ...
- HihoCoder - 1142 三分法练手
中文题面,原函数为三峰函数,先折半再三分 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+11; con ...
- sublim text3中的一些设置
{ "dictionary": "Packages/Language - English/en_US.dic", "font_face&q ...