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

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    输入格式

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入 #1
    5 5
    1 5 4 2 3
    2 2 4
    1 2 3 2
    2 3 4
    1 1 5 1
    2 1 4
    输出 #1
    11
    8
    20

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+9;
    struct node{
        int l,r;
        ll sum,lazy;
    }a[maxn<<2];
    ll s[maxn];
    inline void pushup(int k)
    {
        a[k].sum=(a[k<<1].sum+a[k<<1|1].sum);
    }
    inline void build(int k,int l,int r)
    {
        a[k].l=l,a[k].r=r;
        if(l==r)
        {
            a[k].sum=s[l];
            return;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        pushup(k);
    }
    //void change(int k,int x,int y)
    //{
    //    if(a[k].l==a[k].r)
    //    {
    //        a[k].sum=y;return;
    //    }
    //    int mid=(a[k].l+a[k].r)>>1;
    //    if(x<=mid)change(k<<1,x,y);
    //    else change(k<<1|1,x,y);
    //    update(k);
    //}
    inline void pushdown(int k)
    {
        if(a[k].l==a[k].r)
        {
            a[k].lazy=0;return;
        }
        a[k<<1].sum+=(a[k<<1].r-a[k<<1].l+1)*a[k].lazy;
        a[k<<1|1].sum+=(a[k<<1|1].r-a[k<<1|1].l+1)*a[k].lazy;
        a[k<<1].lazy+=a[k].lazy;
        a[k<<1|1].lazy+=a[k].lazy;
        a[k].lazy=0;
    }
    inline void update(int k,int l,int r,int x)
    {
        if(a[k].l>=l&&a[k].r<=r)
        {
            a[k].sum+=(a[k].r-a[k].l+1)*x;
            a[k].lazy+=x;
            return;
        }
        if(a[k].lazy)pushdown(k);
        int mid=(a[k].l+a[k].r)>>1;
        if(l<=mid)update(k<<1,l,r,x);
        if(r>mid)update(k<<1|1,l,r,x);
    //    else changeplus(k<<1,l,mid,x),changeplus(k<<1|1,mid+1,r,x);
        pushup(k);
    }
    //void changemul(int k,int l,int r,int x)
    //{
    //    
    //}
    
    inline ll query(int k,int l,int r)
    {
        if(a[k].lazy)pushdown(k);
        if(a[k].l>=l&&r>=a[k].r)
        {
            return a[k].sum;
        }
        ll ans=0;
        int mid=(a[k].l+a[k].r)>>1;
        if(l<=mid)ans+=query(k<<1,l,r);
        if(r>mid)ans+=query(k<<1|1,l,r);
    //    else ans+=query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
        return ans;
    }
    int main()
    {
        int n,m,i,L,R,c,opt;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        scanf("%lld",&s[i]);
        build(1,1,n);
        while(m--)
        {
            scanf("%d",&opt);
            if(opt==1)
            {
                scanf("%d%d%d",&L,&R,&c);
                update(1,L,R,c);
            }
            else
            {
                scanf("%d%d",&L,&R);
                printf("%lld
    ",query(1,L,R));
            }
        }
        
    }
    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    java集合-方法
    Java线程池
    java疯狂讲义第18章类的加载和反射
    java疯狂讲义第16章多线程
    JAVA集合-HashMap的实现原理
    类加载-java new一个对象的过程发生了什么/Java对象创建过程
    JVM-java垃圾回收
    JVM-java内存区域
    JVM-java堆-新生代和老年代
    448. 找到所有数组中消失的数字
  • 原文地址:https://www.cnblogs.com/HHHEN/p/11724426.html
Copyright © 2011-2022 走看看