培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)
补坑咯~
今天围绕的是一个神奇的数据结构:线段树。(感觉叫做区间树也挺科学的。)
线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素。
那么这个线段树有什么优势呢?
比如我们要多次查询1-n中的最大值,那么我们如果使用暴力来查找,那么我们每次查找的复杂度就是O(n)
但是如果我们把一个个区间变成树上的一个个点,并且我们严格保证树的深度,那么我们每次查找的复杂度就是O(logn)
这样就能让查询变得更快。
我们先简单讲一下线段树的存储(图中的标号就是线段树数组标号)
这就是线段树的存储方式。
然后我们来学习一下线段树的几个基本操作。
1:单点修改:
我们只要从1号节点往下查,如果在左边就把区间的右端点缩小,否则就把左端点增大,这个操作较为简单,不讲。
2、区间查询:
首先我们先把要查询的区间分为几段,分别刚好对应线段树上的端点,比如说2-5,我们会找到线段树中的9,5,12号节点。
然后我们在回溯的过程中合并答案就好了。
3、区间修改:
这是我们这节课的终点,但其实原理是一样的。
不过判断和区间查询略有区别。
因为区间查询的区间必须和线段树中的节点一一对应,而如果当前的区间在修改区间之内就可以进行修改。
那么区间修改有什么优化的技巧呢?
就是这个——延迟标记!
因为我们知道线段树不一定每次都查询到最底层,所以有时候如果我们把区间修改到树底,那么显然我们的时间复杂度会很高。
但是如果我们存一个延迟标记,在有需要的时候再进行传递,那么就能大大优化复杂度。
下面请看具体代码实现
void pushdown(int k,int l,int r){
mark[ls]+=mark[k];mark[rs]+=mark[k];
int qaq=r-l+;
sum[ls]+=(qaq-(qaq>>))*mark[k];sum[rs]+=(qaq>>)*mark[k];mark[k]=;
}
void update(int l,int r,int a,int b,int k,int add){
if(a<=l&&r<=b){
mark[k]+=add;
sum[k]+=1ll*(r-l+)*add;
return;
}if(mark[k]&&l!=r)pushdown(k,l,r);
if(a<=mid)update(l,mid,a,b,ls,add);
if(b>mid)update(mid+,r,a,b,rs,add);
sum[k]=sum[ls]+sum[rs];
}
long long query(int l,int r,int a,int b,int k){
if(l==a&&r==b)return sum[k];pushdown(k,l,r);
if(b<=mid)return query(l,mid,a,b,ls);
if(a>mid)return query(mid+,r,a,b,rs);
return query(l,mid,a,mid,ls)+query(mid+,r,mid+,b,rs);
}
注:本模板求的是区间和。
培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)的更多相关文章
- hiho一下20周 线段树的区间修改
线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ...
- hihoCode 1078 : 线段树的区间修改
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- UVa 11992 Fast Matrix Operations (线段树,区间修改)
题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...
- hiho一下21周 线段树的区间修改 离散化
离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho ...
- HDU 1698 【线段树,区间修改 + 维护区间和】
题目链接 HDU 1698 Problem Description: In the game of DotA, Pudge’s meat hook is actually the most horri ...
- HZAU 1207 Candies(线段树区间查询 区间修改)
[题目链接]http://acm.hzau.edu.cn/problem.php?id=1207 [题意]给你一个字符串,然后两种操作:1,将区间L,R更新为A或者B,2,询问区间L,R最长的连续的B ...
- hihocoder1078 线段树的区间修改
思路: 线段树区间更新.注意这里是把一个区间的所有数全部赋值为一个新的值. 实现: #include <bits/stdc++.h> using namespace std; ; ], l ...
随机推荐
- MyCAT+MySQL 搭建高可用企业级数据库集群——第2章 MyCat入门
2-1 章节综述 2-2 什么是MyCat 2-3 什么是数据库中间层 2-4 MyCat的主要作用 2-5 MyCat基本元素 2-6 MyCat的安装 2-1 章节综述 1.掌握Mycat的基础概 ...
- (原) MatEditor部- UmateriaEditor中Texture使用过程(1)
@author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ 最后YY需求(手滑)(开黑前弄下,充数,见谅) 1.在理清楚基础套路和细节后,自定义纹理资源,并加 ...
- 洛谷P1379八数码难题
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...
- [译]在Python中如何使用额enumerate 和 zip 来迭代两个列表和它们的index?
enumerate - 迭代一个列表的index和item <Python Cookbook>(Recipe 4.4)描述了如何使用enumerate迭代item和index. 例子如下: ...
- JAVA课程设计 俄罗斯方块
俄罗斯方块 可实现功能 1.账号管理:登录.注册 2.游戏实现:移动.旋转.消除方块统计得分.暂停游戏.暂停后继续游戏.此轮游戏未结束开启新一轮游戏.游戏未结束退出游戏. 3.排行榜:按分数排名.按局 ...
- 有关于PHP的基础知识
(1) l 长字符串表示,必须放在“<<<heredoc”和 “heredoc;”之间.主要是<<<,其次是也可以不使用heredoc. l “<< ...
- 如何使用 window.open() 处理ajax请求返回的url: 在本页面打开并防止浏览器拦截
ajax请求中用window.open()打开请求返回url(例如实现下载功能时),可能会因为跨域问题导致浏览器拦截 解决办法是:在请求前,打开一个窗口,请求成功后将返回的url直接赋值给该窗口的hr ...
- [剑指Offer] 35.数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 前端MVC
闲来没事,画了个张图,是我理解的MVC
- 【题解】Bzoj2125最短路
处理仙人掌 ---> 首先建立出圆方树.则如果询问的两点 \(lca\) 为圆点,直接计算即可, 若 \(lca\) 为方点,则需要额外判断是走环的哪一侧(此时与两个点在环上的相对位置有关.) ...