线段树_[模板]

 题目:洛谷P3372 【模板】线段树 1

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio> 
using namespace std;
int n,m;
long long a[100005];
long long tree[10000005];
int d[10000005][3];
long long lazy[10000005];
void buildtree(int root,int s,int t)
{
    if (s==t)
     {
         tree[root]=a[s];
        d[root][1]=s; d[root][2]=t;
         return;
     }
    buildtree(root*2,s,(s+t)/2);
    buildtree(root*2+1,(s+t)/2+1,t);
    tree[root]=tree[root*2]+tree[root*2+1];
    d[root][1]=s; d[root][2]=t;
}
void down(int root)
{
    if(lazy[root]!=0)
    {
        tree[root*2]+=(d[root*2][2]-d[root*2][1]+1)*lazy[root];
        tree[root*2+1]+=(d[root*2+1][2]-d[root*2+1][1]+1)*lazy[root];
        lazy[root*2]+=lazy[root];
        lazy[root*2+1]+=lazy[root];
        lazy[root]=0;
    }
}
void change(int root,int s,int t,int l,int r,int add)
{
    if (t<l || s>r) return;
    if (l<=s && r>=t)
    {
        tree[root]+=(d[root][2]-d[root][1]+1)*add;
        lazy[root]+=add;
        return;
    }
    down(root);
    int mid=(s+t)/2;
    change(root*2,s,mid,l,r,add);
    change(root*2+1,mid+1,t,l,r,add);
    tree[root]=tree[root*2]+tree[root*2+1];
}
long long find(int root,int s,int t,int l,int r)
{
    if (t<l || s>r) return 0;
    if (l<=s && r>=t)
    {
        return (tree[root]);
    }
    down(root);
    return (find(root*2,s,(s+t)/2,l,min(r,(s+t)/2))+find(root*2+1,(s+t)/2+1,t,max(l,(s+t)/2+1),r));
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
     scanf("%lld",&a[i]);
    buildtree(1,1,n);
    for(int i=1;i<=m;i++)
      {
           long long k,a,b,c;
           scanf("%lld",&k);
           if (k==1)
            {
                 scanf("%lld%lld%lld",&a,&b,&c);
                 change(1,1,n,a,b,c);
          }
         if (k==2)
         {
             scanf("%lld%lld",&a,&b);
             printf("%lld\n",find(1,1,n,a,b));
         }
      }
}

 

posted @ 2020-08-20 19:46  Li_yxxx  阅读(68)  评论(0)    收藏  举报