线段树

poj3468

#include<stdio.h>
#include<string.h>
long long int tree[444444],lazy[444444];
void pushdown(int p,int l,int r)
{
  if(lazy[p])
  {
    int mid=(l+r)/2;
    lazy[2*p]+=lazy[p];
    lazy[2*p+1]+=lazy[p];
    tree[2*p]+=lazy[p]*(mid-l+1);
    tree[2*p+1]+=lazy[p]*(r-mid);
    lazy[p]=0;
  }
}
void build(int p,int l,int r)
{
  if(l==r)
  {
    scanf("%I64d",&tree[p]);
    return;
  }
  int mid=(l+r)/2;
  build(2*p,l,mid);
  build(2*p+1,mid+1,r);
  tree[p]=tree[2*p]+tree[2*p+1];
}
long long int find(int p,int l,int r,int x,int y)
{
  if(x<=l&&y>=r)
    return tree[p];
  pushdown(p,l,r);
  int mid=(l+r)/2;
  long long int sum=0;
  if(x<=mid) sum+=find(2*p,l,mid,x,y);
  if(y>mid) sum+=find(2*p+1,mid+1,r,x,y);
  return sum;
}
void change(int p,int l,int r,int x,int y,int sum)
{
  if(x<=l&&y>=r)
  {
    lazy[p]+=sum;
    tree[p]+=(long long)sum*(r-l+1);
    return;
  }
  pushdown(p,l,r);
  int mid=(l+r)/2;
  if(x<=mid) change(2*p,l,mid,x,y,sum);
  if(y>mid) change(2*p+1,mid+1,r,x,y,sum);
  tree[p]=tree[2*p]+tree[2*p+1];
}
int main()
{
  int m,n,x,y,sum;
  char s[2];
  memset(lazy,0,sizeof(lazy));
  memset(tree,0,sizeof(tree));
  scanf("%d%d",&n,&m);
  build(1,1,n);
  while(m--)
  {
    scanf("%s",s);
    if(s[0]=='Q')
    {
      scanf("%d%d",&x,&y);
      printf("%I64d\n",find(1,1,n,x,y));
    }
    else
    {
      scanf("%d%d%d",&x,&y,&sum);
      change(1,1,n,x,y,sum);
    }
  }
}

你可能感兴趣的:(线段树)