线段树(大三的模板)

Up函数  用来更新父亲节点的值
void push(int w)
{
    sum[w] = sum[2*w]+sum[2*w+1];//更新节点值
}

单点更新 先找出第p个数 然后更新他的值

void add(int p,int d,int l,int r,int w)
{
    if(l==r)
    {
       sum[w]+=d;
          return ;
    }
    int m = (l+r)/2;
    if(p<=m)
        add(p,d,l,m,2*w);
    else
        add(p,d,m+1,r,2*w+1);
    push(w);
}

******************************************

区间求和

int query(int p1,int p2,int l,int r,int w)
{
    if(p1<=l&&p2>=r)//区间被完全覆盖
        return sum[w];
    int m = (l+r)/2;
    int re = 0;
    if(p1<=m)
        re+=query(p1,p2,l,m,2*w);
    if(p2>m)
        re+=query(p1,p2,m+1,r,2*w+1);
    return re;
}

***************************************88

区间更新
down 函数

void pushdown(int w,int m)
{
    if(lz[w])
    {
        lz[2*w]+=lz[w];
        lz[2*w+1] += lz[w];
        sum[2*w] += (lz[w]*(m-(m/2)));
        sum[2*w+1]+=(lz[w]*(m/2));
        lz[w] = 0;//将延迟标记去除
    }
}

void update(int a,int b,int da,int l,int r,int w)
    {
        if(a<=l&&b>=r)
        {
            lz[w] += da;//多次延迟标记
            sum[w]+=da*(r-l+1);
            return ;
        }
        pushdown(w,r-l+1);//更新
        int m = (l+r)/2;
        if(a<=m)
            add(a,b,da,l,m,2*w);
        if(b>m)
            add(a,b,da,m+1,r,2*w+1);
        pushup(w);
    }

线段树(大三的模板),布布扣,bubuko.com

时间: 2024-11-05 12:09:18

线段树(大三的模板)的相关文章

BZOJ4034 树上操作(树剖 线段树大模板)

BZOJ4034 long long 是大坑点 貌似long long 跟int 乘起来会搞事情?... A了这题线段树和树剖的基础OK 嘛 重点过掉的还是线段树区间更新的lazy tag吧 #include<cstdio> #include<cstring> #define N 100001 using namespace std; struct ed{ int nxt,to; }e[N*2]; int ne=0,head[N]; long long int w0[N]; str

线段树(三)

一.线段树的定义 线段树,又名区间树,是一种二叉搜索树. 那么问题来了,啥是二叉搜索树呢? 对于一棵二叉树,若满足: ①它的左子树不空,则左子树上所有结点的值均小于它的根结点的值 ②若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值 ③它的左.右子树也分别为二叉搜索树 那么这就是一棵二叉搜索树. 扯完废话,再回到线段树这里.顾名思义,线段树就是由线段构成的树,它大概长成这样: 对于每一棵线段树上的节点,都有三个值:左区间.右区间以及权值.(当然,在某些情况下它只有左右区间,这个时候线段

线段树详解及模板 (转载)

一步一步理解线段树 目录 一.概述 二.从一个例子理解线段树 创建线段树 线段树区间查询 单节点更新 区间更新 三.线段树实战 -------------------------- 一 概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(logn). 线段树的每个节点表示一个区间,子节点则分别表示父节点的左右半区间,例如父亲的区间是[a,b],那么(c=(a+b)

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放

(HDU 1698) Just a Hook(线段树)-附通用模板

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37787    Accepted Submission(s): 18409 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing

hdu1698 Just a Hook(线段树+区间修改+区间查询+模板)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 54923    Accepted Submission(s): 25566 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of

线段树个人理解及模板

一.线段树的相关定义及用途 (1)线段树的定义 线段树是一种可以加快对区间进行更新以及查询的一种树状结构,类似于将一个区间的及其子区间的相关信息存储在一颗二叉树中. (2)线段树的用途大致为以下几种 1>某个子区间进行区间更新 2>查询某个子区间的总和 3>查询某个子区间的最值 二.线段树的建立 (1)节点的内容(一个节点代表一个区间) 1>NodeLeft-----该区间的左边界 2>NodeRight-----该区间的右边界 3>NodeMin--------该区间

树状数组与线段树(三)

找规律题 1.螺旋折线 如下图所示的螺旋折线经过平面上所有整点恰好一次. 对于整点 (X,Y),我们定义它到原点的距离 dis(X,Y) 是从原点到 (X,Y) 的螺旋折线段的长度. 例如 dis(0,1)=3,dis(−2,−1)=9 给出整点坐标 (X,Y),你能计算出 dis(X,Y)吗? 输入格式 包含两个整数 X,Y. 输出格式 输出一个整数,表示 dis(X,Y). 数据范围 −109≤X,Y≤109 输入样例: 0 1 输出样例: 3解题思路:这是一道找规律题,我们可以将整个坐标都

【区间合并线段树】HDU 4509 模板

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN=100000+50; const int rt=0; vector<