线段树模板2(洛谷p3372)(区间修改+区间查询)

例题:https://www.luogu.org/problem/show?pid=3373

#include<iostream>
#include<cstdio>
using namespace std;
int x,n,m,y,z,ch,mid,a[1000000];
long long f[1000000],lazy[1000000];

//建树
void build(int root,int l,int r)
{
    int mid;
    if (l==r) 
    {
      f[root]=a[l];
      return;
    }
    
    mid=(l+r)/2;
    build(root*2,l,mid);
    if (mid+1<=r) build(root*2+1,mid+1,r);
    f[root]=f[root*2]+f[root*2+1];
}

//下放懒标记
void pushdown(int root,int nowl,int nowr)
{
    if (lazy[root]==0) return;
    int mid=(nowl+nowr)/2;
    f[root*2]+=lazy[root]*(mid-nowl+1);
    f[root*2+1]+=lazy[root]*(nowr-mid);
    lazy[root*2]+=lazy[root];
    lazy[root*2+1]+=lazy[root];
    lazy[root]=0;
}
//修改
void update(int root,int nowl,int nowr,int l,int r,int k)
{
    int mid;
    if ((nowl>=l)&&(nowr<=r)) 
    {
      f[root]+=(nowr-nowl+1)*k;
      lazy[root]+=k;
      return;
    }
    if ((nowl>r)||(nowr<l)) return;
    pushdown(root,nowl,nowr);
    mid=(nowl+nowr)/2;
    update(root*2,nowl,mid,l,r,k);
    if (mid+1<=nowr) update(root*2+1,mid+1,nowr,l,r,k);
    f[root]=f[root*2]+f[root*2+1];
}

//查询
long long query(int root,int nowl,int nowr,int l,int r)
{
  int mid;
  if (nowl>nowr) return 0;
  if ((nowl>r)||(nowr<l)) return 0;
  if ((nowl>=l)&&(nowr<=r)) return f[root];
  mid=(nowl+nowr)/2;
  pushdown(root,nowl,nowr);
  return (query(root*2,nowl,mid,l,r)+
          query(root*2+1,mid+1,nowr,l,r));
}

int main()
{
  scanf("%d%d",&n,&m);
  for (int i=1;i<=n;i++) scanf("%d",&a[i]);
  build(1,1,n); 
  for (int i=1;i<=m;i++)
  {
    scanf("%d",&ch);
    if (ch==1) 
    {
      scanf("%d%d%d",&x,&y,&z);
      update(1,1,n,x,y,z);
    }
    else 
    {
      scanf("%d%d",&x,&y);
      printf("%lld
",query(1,1,n,x,y));
    } 
  }
}#include<iostream>
#include<cstdio>
using namespace std;
int x,n,m,y,z,ch,mid,a[1000000];
long long f[1000000],lazy[1000000];
void build(int root,int l,int r)
{
    int mid;
    if (l==r) 
    {
      f[root]=a[l];
      return;
    }
    
    mid=(l+r)/2;
    build(root*2,l,mid);
    if (mid+1<=r) build(root*2+1,mid+1,r);
    f[root]=f[root*2]+f[root*2+1];
}
void pushdown(int root,int nowl,int nowr)
{
    if (lazy[root]==0) return;
    int mid=(nowl+nowr)/2;
    f[root*2]+=lazy[root]*(mid-nowl+1);
    f[root*2+1]+=lazy[root]*(nowr-mid);
    lazy[root*2]+=lazy[root];
    lazy[root*2+1]+=lazy[root];
    lazy[root]=0;
}
void update(int root,int nowl,int nowr,int l,int r,int k)
{
    int mid;
    if ((nowl>=l)&&(nowr<=r)) 
    {
      f[root]+=(nowr-nowl+1)*k;
      lazy[root]+=k;
      return;
    }
    if ((nowl>r)||(nowr<l)) return;
    pushdown(root,nowl,nowr);
    mid=(nowl+nowr)/2;
    update(root*2,nowl,mid,l,r,k);
    if (mid+1<=nowr) update(root*2+1,mid+1,nowr,l,r,k);
    f[root]=f[root*2]+f[root*2+1];
}
long long query(int root,int nowl,int nowr,int l,int r)
{
  int mid;
  if (nowl>nowr) return 0;
  if ((nowl>r)||(nowr<l)) return 0;
  if ((nowl>=l)&&(nowr<=r)) return f[root];
  mid=(nowl+nowr)/2;
  pushdown(root,nowl,nowr);
  return (query(root*2,nowl,mid,l,r)+
          query(root*2+1,mid+1,nowr,l,r));
}
int main()
{
  scanf("%d%d",&n,&m);
  for (int i=1;i<=n;i++) scanf("%d",&a[i]);
  build(1,1,n); 
  for (int i=1;i<=m;i++)
  {
    scanf("%d",&ch);
    if (ch==1) 
    {
      scanf("%d%d%d",&x,&y,&z);
      update(1,1,n,x,y,z);
    }
    else 
    {
      scanf("%d%d",&x,&y);
      printf("%lld
",query(1,1,n,x,y));
    } 
  }
}

序:

原文地址:https://www.cnblogs.com/2014nhc/p/6369424.html