poj 3468 A Simple Problem with Integers(线段树区间更新)

来源:互联网 发布:阿里云服务器如何退款 编辑:程序博客网 时间:2024/05/16 09:18

题意:一个数列,每次操作可以是将某区间数字都加上一个相同的整数,也可以是询问一个区间中所有数字的和。(这里区间指的是数列中连续的若干个数)对每次询问给出结果。

分析:线保留型线段树,线段树中每个节点有两个变量:增量与和,一个记录当前节点对应区间被整体增加了几,另一个记录该区间的真子区间被增加了之后的和是多少。(该区间数字当前和=和+增量×区间长度)

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0xFFFFFFFF#define pi acos(-1.0)#define eps 1e-4#define maxn 100010#define MOD 1000000007struct node{    int l,r;    long long sum,lazy;}tree[maxn*4];void pushup(int pos){    tree[pos].sum = tree[pos<<1].sum + tree[pos<<1|1].sum;}void pushdown(int pos){    if(!tree[pos].lazy)        return;    tree[pos<<1].sum += (tree[pos<<1].r-tree[pos<<1].l+1)*tree[pos].lazy;    tree[pos<<1|1].sum += (tree[pos<<1|1].r-tree[pos<<1|1].l+1)*tree[pos].lazy;    tree[pos<<1].lazy += tree[pos].lazy;    tree[pos<<1|1].lazy += tree[pos].lazy;    tree[pos].lazy = 0;}void build(int l,int r,int pos){    tree[pos].l = l;    tree[pos].r = r;    tree[pos].sum = 0;    tree[pos].lazy = 0;    if(l == r)    {        scanf("%I64d",&tree[pos].sum);        return;    }    int mid = (l+r)/2;    build(l,mid,pos<<1);    build(mid+1,r,pos<<1|1);    pushup(pos);}                                                   //建树                                                  //查询操作void update(int l,int r,int pos,int add){    if(tree[pos].l == l && tree[pos].r == r)    {        tree[pos].sum += (r-l+1)*add;        tree[pos].lazy += add;        return ;    }    pushdown(pos);    int mid = (tree[pos].l + tree[pos].r) >> 1;    if(r <= mid)        update(l,r,pos<<1,add);    else if(l > mid)        update(l,r,pos<<1|1,add);    else    {        update(l,mid,pos<<1,add);        update(mid+1,r,pos<<1|1,add);    }    pushup(pos);}                                         //自上而下更新节点long long query(int l,int r,int pos){    if(l == tree[pos].l && r == tree[pos].r)        return tree[pos].sum;    pushdown(pos);    int mid = (tree[pos].l+tree[pos].r)>>1;    if(r <= mid)        return query(l,r,pos<<1);    else if(l > mid)        return query(l,r,pos<<1|1);    else        return query(l,mid,pos<<1) + query(mid+1,r,pos<<1|1);}int main(){    int t,n,m,C = 1;    //scanf("%d",&t);    while(scanf("%d%d",&n,&m) != EOF)    {        int a,b,c;        char ch;        build(1,n,1);        for(int i = 1; i <= m; i++)        {            getchar();            scanf("%c%d%d",&ch,&a,&b);            if(ch == 'Q')                printf("%I64d\n",query(a,b,1));            else            {                scanf("%d",&c);                update(a,b,1,c);            }        }    }    return 0;}


0 0