zoukankan      html  css  js  c++  java
  • 线段树板子

    板子:(秋实大哥与花)

    线段树要开四倍空间,

    push_down中的lazy操作,简言之,更新到一个区间时,按照updata就一直更新下去,而如果在这个区间内的话,直接打lazy标记更新区间,而没必要updata下去;

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    const int N=500000;
    typedef long long LL;
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    int n,m;
    int a[maxn];
    struct node{
        int l,r;
        long long sum,lazy;
        void update(long long x)
        {
            sum+=1ll*(r-l+1)*x;
            lazy+=x;
        }
    
    }tree[maxn*4];
    void push_up(int x)//自下而上
    {
        tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
    }
    void push_down(int x)//自上而下
    {
        int lazyval=tree[x].lazy;
        if(lazyval)
        {
            tree[x<<1].update(lazyval);
            tree[x<<1|1].update(lazyval);//这里x<<1|1=x*2+1
            tree[x].lazy=0;//一定要清除掉
        }
    }
    void build(int x,int l,int r)//x即为root(根节点)
    {
        tree[x].l=l,tree[x].r=r;
        tree[x].sum=tree[x].lazy=0;//初始化
        if(l==r)
            tree[x].sum=a[l];
        else
        {
            int mid=(l+r)/2;
            build(x<<1,l,mid);//左子树
            build(x<<1|1,mid+1,r);//右子树
            push_up(x);//更新sum值
        }
    }
    void update(int x,int l,int r,long long val)
    {
        int L=tree[x].l,R=tree[x].r;
        if(l<=L&&R<=r)//保证在区间内
            tree[x].update(val);
        else
        {
            push_down(x);
            int mid=(L+R)/2;
            if(mid>=l) update(x<<1,l,r,val);//链状更新
            if(r>mid) update(x<<1|1,l,r,val);
            push_up(x);//自下而上的更新sum
        }
    }
    long long quary(int x,int l,int r)
    {
        int L=tree[x].l,R=tree[x].r;
        if(l<=L&&R<=r)
            return tree[x].sum;
        else
        {
            push_down(x);
            long long ans=0;
            int mid=(L+R)/2;
            if(mid>=l) ans+=quary(x<<1,l,r);
            if(r>mid) ans+=quary(x<<1|1,l,r);
            push_up(x);
            return ans;
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1; i<=n; i++)
                scanf("%d",&a[i]);
            scanf("%d",&m);
            build(1,1,n);
            for(int i=1; i<=m; i++)
            {
                int l,r,val;
                scanf("%d%d%d",&l,&r,&val);
                update(1,l,r,val);
                printf("%lld
    ",quary(1,l,r));
            }
        }
        return 0;
    }
  • 相关阅读:
    【Mocha.js 101】Mocha 入门指南
    CSS 中 Font-Family 中英文对照表
    Android Studio中找出不再使用的资源
    Java反射机制实战——字段篇
    python进阶——day02、03面向对象进阶
    python进阶_day01面对对象编程基础
    day05(文件配置命令和远程登录)
    day04(磁盘管理与目录介绍)
    day03(系统启动及常用的Linux命令的基本使用)
    day02(操作系统简介和Linux的安装与常用命令简介)
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/12676304.html
Copyright © 2011-2022 走看看