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,第二种是 ...
随机推荐
- The server of Apache (四)——配置防盗链和隐藏版本信息
一.防盗链 防盗链就是防止别人的网站代码里面盗用我们服务器的图片.文件.视频等相关资源,比如我们的网页的图片有链接,别人把链接复制粘贴到他们的服务器页面里,图片不在他们自己的网站里,每次打开他们的网站 ...
- C语言中静态断言的使用
编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作异常处理的高级形式,用于代码调试. #define _CRT_SECURE_NO_WARNINGS //关闭安全监察 ...
- 1. C语言对文件的操作
1. 文件常见输入输出函数与屏幕.键盘输入输出函数的对比,如:fprintf.fscanf等. #define _CRT_SECURE_NO_WARNINGS #include <stdio.h ...
- jQuery EasyUI Datagrid组件默认视图分析
在Datagrid基础DOM结构的一文中,我对Datagrid组件的骨架做了很详细的描述.有了骨架还并不完整,还得有血有肉有衣服穿才行.强大的Datagrid组件允许我们自己定义如何在基础骨架上长出健 ...
- 4A - Horse
打表找规律 #include <iostream> #include <queue> using namespace std; ][]; ]{, , , , -, -, -, ...
- BZOJ3065 带插入区间K小值 || 洛谷P4278
这是一道让我崩溃的题...... 然鹅洛谷上时限被改然后只有20分......好像所有人都被卡了(雾) 由于替罪羊树不是依靠旋转操作而是依靠暴力重构的方式维护树的平衡,所以我们可以考虑使用替罪羊树套区 ...
- ABP项目后台初始化数据库
设置host为启动项,并修改连接字符串 在程序包管理控制台中,默认项目选中EFCore 执行Update-Database命令
- POJ - 1011 剪枝练习
题意:给定n条拆掉的棍子,问能凑成最短的多条相同长度棍子的最短长度 x:当前第几条正在合成的棍子 y:目前正在尝试的拆掉的棍子 z:当前长度 剪枝方案: 1.按照长度单调性排序,减少重复搜索 2.如果 ...
- 04-树6 Complete Binary Search Tree (30 分)
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...
- [转] Mysql命令基础
[From] http://c.biancheng.net/cpp/u/mysql_ml/ 连接Mysql数据库 mysql命令格式: mysql -h主机地址 -u用户名 -p用户密码 1) 连接到 ...