补坑咯~

今天围绕的是一个神奇的数据结构:线段树。(感觉叫做区间树也挺科学的。)

线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素。

那么这个线段树有什么优势呢?

比如我们要多次查询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)的更多相关文章

  1. hiho一下20周 线段树的区间修改

    线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...

  2. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...

  3. hihoCode 1078 : 线段树的区间修改

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  4. hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  5. UVa 11992 Fast Matrix Operations (线段树,区间修改)

    题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...

  6. hiho一下21周 线段树的区间修改 离散化

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

  7. HDU 1698 【线段树,区间修改 + 维护区间和】

    题目链接 HDU 1698 Problem Description: In the game of DotA, Pudge’s meat hook is actually the most horri ...

  8. HZAU 1207 Candies(线段树区间查询 区间修改)

    [题目链接]http://acm.hzau.edu.cn/problem.php?id=1207 [题意]给你一个字符串,然后两种操作:1,将区间L,R更新为A或者B,2,询问区间L,R最长的连续的B ...

  9. hihocoder1078 线段树的区间修改

    思路: 线段树区间更新.注意这里是把一个区间的所有数全部赋值为一个新的值. 实现: #include <bits/stdc++.h> using namespace std; ; ], l ...

随机推荐

  1. 用Python 的一些用法与 JS 进行类比,看有什么相似?

    Python 是一门运用很广泛的语言,自动化脚本.爬虫,甚至在深度学习领域也都有 Python 的身影.作为一名前端开发者,也了解 ES6 中的很多特性借鉴自 Python (比如默认参数.解构赋值. ...

  2. 让PC版网站在移动端原样式显示

    一般PC网站在移动端显示效果往往和PC版原样式不同,为了在移动端下还原原PC站样式,可以采用以下方式解决: 1) 去掉页头的: <meta name="viewport" c ...

  3. LeetCode 29——两数相除

    1. 题目 2. 解答 2.1. 方法一 题目要求不能使用乘法.除法和除余运算,但我们可以将除法转移到对数域. \[ \frac{a}{b} = e^{\frac{lna}{lnb}} = e^{ln ...

  4. POJ 2135 Farm Tour(最小费用最大流)

    Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...

  5. URAL 1736 Chinese Hockey(网络最大流)

    Description Sergey and Denis closely followed the Chinese Football Championship, which has just come ...

  6. Android Studio环境解读

    一.使用IDE开发APP的流程 要熟悉一个新的IDE,可依次完成以下流程: 二.相关术语解析 Dalvik: Android特有的虚拟机,和JVM不同,Dalvik虚拟机非常适合在移动终端上使用! A ...

  7. C#中async和await用法

    .net 4.5中新增了async和await这一对用于异步编程的关键字. async放在方法中存在await代码的方法中,await放在调用返回Task的方法前. class Class1 { pr ...

  8. C#与Javascript变量、函数之间的相互调用

    原文地址:http://blog.csdn.net/wonsoft/article/details/2595743 C#与Javascript变量.函数之间的相互调用  一.javascript调用C ...

  9. hw_breakpoint使用方法

    hw_breakpoint 使用方法 kprobe在 do_page_fault 函数中不能使用,那么如果真要在这里打点怎么办呢?看看hw_breakpoint是否可用: 事实证明,即便 hw_bre ...

  10. [CF1041E]Tree Reconstruction

    题目大意:有一棵树,现在给你每条树边被去掉时,形成的两个联通块中点的最大的编号分别是多少,问满足条件的树存不存在,存在输出方案 题解:一条边的两个编号中较大的一个一定是$n$,否则无解. 开始构造这棵 ...