线段树板子

板子:(秋实大哥与花)

线段树要开四倍空间,

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\n",quary(1,l,r));
        }
    }
    return 0;
}

 

posted on 2020-04-10 21:35  mmn  阅读(157)  评论(0编辑  收藏  举报