线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能。

同时,它也很重要。如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了。不过,随着时代的进步,题目也越来越变态,线段树更多时候则是你算法时间复杂度的优化。

这是单点查询的代码。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; int n;
int a[]; struct node
{
int l;
int r;
int sum;
} t[]; void build (int i,int l,int r)
{
t[i].l=l;
t[i].r=r;
int mid=l+r>>;
if (l==r)
{
t[i].sum=a[l];return ;
} build(i<<,l,mid);
build((i<<)+,mid+,r); t[i].sum=t[i<<].sum+t[(i<<)+].sum; return ;
} void update(int i,int p,int k)
{
if (t[i].l==t[i].r)
{
t[i].sum=k;
return;
} int mid=t[i].l+t[i].r>>;
if (p<=mid) update(i<<,p,k);
if (p>mid) update((i<<)+,p,k);
t[i].sum=t[i<<].sum+t[(i<<)+].sum; return ;
} int getsum(int i,int l,int r)
{
int mid=(t[i].l+t[i].r)>>;
if (l<=t[i].l&&t[i].r<=r) return t[i].sum;
if (r<=mid) return getsum(i<<,l,r);
if (l>mid) return getsum((i<<)+,l,r); return getsum(i<<,l,r)+getsum((i<<)+,l,r);
} int main()
{
int m;
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++)
{
scanf("%d",&a[i]);
}
build(,,n);
while (m--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if (x==)
{
update(,y,z);
}
else printf("%d\n",getsum(,y,z));
} return ;
}

下面是区间修改的代码。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
using namespace std; struct node
{
int l,r,s,d;
} t[];
int n,m;
int a[]; void pushup(int x)
{
t[x].s=t[x<<].s+t[(x<<)+].s;
return;
} void pushdown(int x)
{
int mid=(t[x].l+t[x].r)>>;
int d=t[x].d;
t[x<<].d+=d;t[(x<<)+].d+=d;
t[x<<].s+=(mid-t[x].l+)*d;
t[(x<<)+].s+=(t[x].r-mid)*d;
return;
} void build(int i,int l,int r)
{
t[i].l=l;
t[i].r=r;
t[i].d=;
if (l==r)
{
t[i].s=a[l];
return ;
} int mid=l+r>>; build(i<<,l,mid);
build((i<<)+,mid+,r); pushup(i);
return;
} int getsum(int i,int l,int r)
{
int mid=t[i].l+t[i].r>>;
if (l<=t[i].l&&t[i].r<=r)
{
return t[i].s;
}
int d=t[i].d;
if (!d) pushdown(i);
int ret=;
if (mid>=l) ret+=getsum(i<<,l,r);
if (mid<r) ret+=getsum((i<<)+,l,r); return ret;
} void update(int i,int l,int r,int del)
{
if (t[i].l==t[i].r)
{
t[i].d+=del;
t[i].s+=(t[i].l-t[i].r+)*del;
return ;
} int mid=t[i].l+t[i].r>>;
if (!t[i].d) pushdown(i);
if (mid>=l) update(i<<,l,r,del);
if (mid<r) update((i<<)+,l,r,del);
pushup(i);
} int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
build (,,n); for (int i=;i<=m;i++)
{
int x,y,z,d;
scanf("%d",&x);
if (x==)
{
scanf("%d%d%d",&y,&z,&d);
update(,y,z,d);
}
if (x==)
{
scanf("%d%d",&y,&z);
printf("%d\n",getsum(,y,z));
}
} return ;
}

线段树:Segment Tree(单点修改/区间修改模板) C++的更多相关文章

  1. 『线段树 Segment Tree』

    更新了基础部分 更新了\(lazytag\)标记的讲解 线段树 Segment Tree 今天来讲一下经典的线段树. 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间 ...

  2. 线段树(Segment Tree)(转)

    原文链接:线段树(Segment Tree) 1.概述 线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即“子数组”),因而常用于解决数列维护问题,基本能保证每个操作的复杂度为O(lg ...

  3. BZOJ4999:This Problem Is Too Simple!(DFS序&树上差分&线段树动态开点:区间修改单点查询)

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  4. BZOJ.4695.最假女选手(线段树 Segment tree Beats!)

    题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...

  5. 【数据结构系列】线段树(Segment Tree)

    一.线段树的定义 线段树,又名区间树,是一种二叉搜索树. 那么问题来了,啥是二叉搜索树呢? 对于一棵二叉树,若满足: ①它的左子树不空,则左子树上所有结点的值均小于它的根结点的值 ②若它的右子树不空, ...

  6. 浅谈线段树 Segment Tree

    众所周知,线段树是algo中很重要的一项! 一.简介 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在 ...

  7. 线段树(segment tree)

    线段树在一些acm题目中经常见到,这种数据结构主要应用在计算几何和地理信息系统中.下图就为一个线段树: (PS:可能你见过线段树的不同表示方式,但是都大同小异,根据自己的需要来建就行.) 1.线段树基 ...

  8. poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)

    题目链接:http://poj.org/problem?id=2763 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值. 题解:简单的树链剖分. #i ...

  9. 线段树 Interval Tree

    一.线段树 线段树既是线段也是树,并且是一棵二叉树,每个结点是一条线段,每条线段的左右儿子线段分别是该线段的左半和右半区间,递归定义之后就是一棵线段树. 例题:给定N条线段,{[2, 5], [4, ...

  10. Libre OJ 130、131、132 (树状数组 单点修改、区间查询 -> 区间修改,单点查询 -> 区间修改,区间查询)

    这三题均可以用树状数组.分块或线段树来做 #130. 树状数组 1 :单点修改,区间查询 题目链接:https://loj.ac/problem/130 题目描述 这是一道模板题. 给定数列 a[1] ...

随机推荐

  1. phpcms v9为联动菜单字段添加验证提醒功能 解决标题不能为空

    v9系统中,如果你在模型中添加了联动菜单字段就算你在字段设置中设置了最小值为1,提交内容之前你不选择联动菜单中的值,也不会出现类似类似“标题不能为空”这样的提示下面提供解决办法打开phpcms\lib ...

  2. DedeCMS中最重要的四类表

    栏目(类别): dede_arctype (dede数据库设计者认为:不管你是存放什么样的数据(软件,商品,电影..)都应该属于某个栏目(类型)) 内容主表:dede_archives (织梦数据库的 ...

  3. Flask源码阅读笔记(一)

    作者:acezio链接:https://zhuanlan.zhihu.com/p/21358368来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. flask的url r ...

  4. easyui最小化后停留在页面的右下角

    0.此方法没有什么技术含量,纯属于自己瞎想的!如果有的好方法,请留言告之谢谢!! 1.直接上代码: $('#winId').window({ onMinimize: function () { //最 ...

  5. js 解析 json

    1.简单的json格式 { "user": [ { "name":"name1", "age":24, "se ...

  6. 机器人操作系统ROS | 简介篇

    同样,从个人微信公众号Nao(ID:qRobotics)搬运. 前言 先放一个ROS Industrial一周年剪辑视频. ROS已经发布八周年了,在国外科研机构中非常受欢迎.目前,以美国西南研究院为 ...

  7. arm linux上的第一个应用程序 BOA移植

    1. 首先, linux在开发板上能跑起来了. 包括网络驱动也有了, ifconfig之后, 能看到在rcS里面设置的IP, 也能ping通windows主机了, 当然, 也要window关掉防火墙才 ...

  8. [LeetCode 115] - 不同子序列(Distinct Subsequences)

    问题 给出字符串S和T,计算S中为T的不同的子序列的个数. 一个字符串的子序列是一个由该原始字符串通过删除一些字母(也可以不删)但是不改变剩下字母的相对顺序产生的一个新字符串.如,ACE是ABCDE的 ...

  9. AndroidManifest.xml 文件里面的内容介绍

    <?xml version="1.0" encoding="utf-8"?> <!--package 包表示整个java应用程序的主要包名,而 ...

  10. C51与汇编混合编程详解

    C51和汇编混合编程(1)-C语言中嵌入汇编 1.在 C文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma ASM ;Assembler Code Here #pragma ENDASM ...