POJ 3468<线段树,区间add>

题目连接

//位运算
 k<<1   相当于  k*2
 k<<1|1 相当于 k*2+1
/*
  修改区间内的值,并且维护区间和。
  详见代码
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long  LL;
const int maxn=100000+10;
int a[maxn];
struct tree
{
    int l,r;
    LL sum;
    LL Inc;//延迟标记变量,表示[l,r]区间每个数增加Inc.

}f[maxn*4];
void bulid(int i,int l,int r)//maketree
{
    f[i].l=l;
    f[i].r=r;
    f[i].Inc=0;
    if(l==r)
    {
        f[i].sum=a[l];//是a[l]不能是a[i],i代表的是节点的编号,在最后一行,l或者r代表的是第i个节点的次序。
        return ;
    }
    int mid=(l+r)>>1;
    bulid(i<<1, l, mid);
    bulid(i<<1|1, mid+1, r);
    f[i].sum=f[i<<1].sum+f[i<<1|1].sum;//维护和
}
void add(int i,int a,int b,LL c)
{
    if(f[i].l==a&&f[i].r==b)//区间重合,直接标记Inc+=c;
    {
        f[i].Inc+=c;
        return ;
    }
  //区间不重合,更新当前区间的sum,pushdown
    f[i].sum+=c*(b-a+1);
    int mid=(f[i].l+f[i].r)>>1;
    if(b<=mid)
        add(i<<1, a, b, c);
    else if(a>=mid+1)
        add(i<<1|1, a, b, c);
    else
    {
        add(i<<1, a,mid, c);
        add(i<<1|1,mid+1,b,c);
    }
}
LL query(int i,int a,int b)//查询
{
    if(f[i].l==a&&f[i].r==b)//区间重合
    {
        return f[i].sum+f[i].Inc*(b-a+1);
    }

    f[i].sum+=(f[i].r-f[i].l+1)*f[i].Inc;//相当于pushdown
    int mid=(f[i].l+f[i].r)>>1;
    add(i<<1, f[i].l, mid, f[i].Inc);
    add(i<<1|1,mid+1,f[i].r,f[i].Inc);
    f[i].Inc=0;

    if(b<=mid)
        return query(i<<1, a, b);
    else if(a>=mid+1) return query(i<<1|1, a, b);
    else return query(i<<1, a, mid)+query(i<<1|1, mid+1,b);
}
int main ()
{
    int n,m;
    char s[5];
    int l,r;
    LL c;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        bulid(1, 1, n);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);
            if(s[0]=='Q')
            {
                scanf("%d%d",&l,&r);
                printf("%lld
",query(1, l, r));
            }
            else
            {
                scanf("%d%d%lld",&l,&r,&c);
                add(1, l, r, c);
            }
        }
    }
    return 0;
}
想的太多,做的太少。
原文地址:https://www.cnblogs.com/pealicx/p/6115622.html