poj3468A Simple Problem with Integers(线段树成段更新)

->题目请戳这里<-

题目大意:红果果的线段树,给n个数,2种操作,Q a b,查询a到b这个区间和,C a b c,a到b区间每个数加上c。

题目分析:线段树维护区间和,要加lazy标记。

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
typedef __int64 ll;
struct node
{
    int lazy;
    ll sum,add;
}lcm[N<<2];
int m,n;

void build(int num,int s,int e)
{
    lcm[num].lazy = 0;
    lcm[num].sum = lcm[num].add = 0;
    if(s == e)
        return;
    int mid = (s + e)>>1;
    build(num<<1,s,mid);
    build(num<<1|1,mid + 1,e);
}

void insert(int num,int s,int e,int l,int r,int val)
{
    if(s == l && e == r)
    {
        lcm[num].lazy = 1;
        lcm[num].add += val;
        return;
    }
    if(lcm[num].lazy == 1)
    {
        lcm[num<<1].lazy = 1;
        lcm[num<<1|1].lazy = 1;
        lcm[num<<1].add += lcm[num].add;
        lcm[num<<1|1].add += lcm[num].add;
        lcm[num].add = 0;
        lcm[num].lazy = 0;
    }
    int mid = (s + e)>>1;
    if(r <= mid)
    {
        insert(num<<1,s,mid,l,r,val);
    }
    else
    {
        if(l > mid)
            insert(num<<1|1,mid + 1,e,l,r,val);
        else
        {
            insert(num<<1,s,mid,l,mid,val);
            insert(num<<1|1,mid + 1,e,mid + 1,r,val);
        }
    }
    lcm[num].sum = lcm[num<<1].sum + lcm[num<<1|1].sum;
    lcm[num].sum += lcm[num<<1].add * (mid + 1 - s) + lcm[num<<1|1].add * (e - mid);
}

ll query(int num,int s,int e,int l,int r)
{
    if(s == l && e == r)
    {
        return lcm[num].add * (e - s + 1) + lcm[num].sum;
    }
    if(lcm[num].lazy == 1)
    {
        lcm[num<<1].lazy = lcm[num<<1|1].lazy = 1;
        lcm[num<<1].add += lcm[num].add;
        lcm[num<<1|1].add += lcm[num].add;
        lcm[num].sum += (e - s + 1) * lcm[num].add;
        lcm[num].add = 0;
        lcm[num].lazy = 0;
    }
    
    int mid = (s + e)>>1;
    if(r <= mid)
        return query(num<<1,s,mid,l,r);
    else
    {
        if(l > mid)
            return query(num<<1|1,mid + 1,e,l,r);
        else
        {
            return query(num<<1,s,mid,l,mid) + query(num<<1|1,mid + 1,e,mid + 1,r);
        }
    }
}

int main()
{
    int i;
    int a,b,c;
    char op[3];
    while(scanf("%d%d",&n,&m) != EOF)
    {
        build(1,1,n);
        for(i = 1;i <= n;i ++)
        {
            scanf("%d",&a);
            insert(1,1,n,i,i,a);
        }
        while(m --)
        {
            scanf("%s",op);
            if(op[0] == 'Q')
            {
                scanf("%d%d",&a,&b);
                printf("%I64d\n",query(1,1,n,a,b));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                insert(1,1,n,a,b,c);
            }
        }
        //printf("%I64d\n",lcm[1].sum);
    }
    return 0;
}
//6332K	1954MS


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