POJ 3468 A Simple Problem with Integers

题目链接:http://poj.org/problem?id=3468


题意:给出n个数,2种操作,一种将[l,r]中得数同时加上val,一种是查询[l,r]所有数之和


思路:又是区间更新和查询(树状数组就可以很好的解决),也是典型的线段树,lazy标志用法和之前有些不一样,每次更新成新区间的和与旧区间和的差值,查询时要把lazy标志向子节点推(这一步另外写一个函数会好看很多,lazy更新时犯了点小错查了很久,被angod狠狠的嘲笑了)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100030
#define LL long long
using namespace std;

struct Tree
{
    int l,r;
    LL date;
}tree[maxn*3];

int s[maxn];
LL lazy[maxn*3];

void build(int root,int l,int r)
{
    tree[root].l=l;
    tree[root].r=r;
    if (l==r)
    {
        tree[root].date=s[l];
        return;
    }

    int mid=(l+r)>>1;
    build (root<<1,l,mid);
    build (root<<1|1,mid+1,r);
    tree[root].date=tree[root<<1].date+tree[root<<1|1].date;
}

void update(int root,int l,int r,int val)
{
    if (tree[root].l>=l && tree[root].r<=r)
    {
        tree[root].date+=(LL)val*(tree[root].r-tree[root].l+1);
        lazy[root]+=val;
        return;
    }

    if (lazy[root]!=0)
    {
        lazy[root<<1]+=lazy[root];
        lazy[root<<1|1]+=lazy[root];
        tree[root<<1].date+=lazy[root]*(tree[root<<1].r-tree[root<<1].l+1);
        tree[root<<1|1].date+=lazy[root]*(tree[root<<1|1].r-tree[root<<1|1].l+1);
        lazy[root]=0;
    }

    int mid=(tree[root].l+tree[root].r)>>1;
    if (l<=mid) update(root<<1,l,r,val);
    if (r>mid) update(root<<1|1,l,r,val);
    tree[root].date=tree[root<<1].date+tree[root<<1|1].date;
}

long long que(int root,int l,int r)
{
    if (tree[root].l==l && tree[root].r==r)
    {
        return tree[root].date;
    }

    if (lazy[root]!=0)
    {
        lazy[root<<1]+=lazy[root];
        lazy[root<<1|1]+=lazy[root];
        tree[root<<1].date+=lazy[root]*(tree[root<<1].r-tree[root<<1].l+1);
        tree[root<<1|1].date+=lazy[root]*(tree[root<<1|1].r-tree[root<<1|1].l+1);
        lazy[root]=0;
    }
    int mid=(tree[root].l+tree[root].r)>>1;
    if (r<=mid) return que(root<<1,l,r);
    else if (l>mid) return que(root<<1|1,l,r);
    else return que(root<<1,l,mid)+que(root<<1|1,mid+1,r);
}


int main()
{
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        memset(lazy,0,sizeof(lazy));
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
        }
        build(1,1,n);
        for (int i=0;i<m;i++)
        {
            char op;
            cin>>op;
            if (op=='Q')
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%I64d\n",que(1,a,b));
            }
            else
            {
                int a,b,p;
                scanf("%d%d%d",&a,&b,&p);
                update(1,a,b,p);
            }
        }
    }
}




你可能感兴趣的:(数据结构,ACM)