poj 3468 A Simple Problem with Integers(线段树|成段更新,区间查询)

链接:

http://poj.org/problem?id=3468


题目大意:

有N个整数:A1, A2, ... , AN。 然后对这个整数序列有两种操作:

1. C  a  b  c :   把Aa, Aa+1, ... , Ab所有元素都加上c

2.  Q  a  b :     查询Aa, Aa+1, ... , Ab之和。


分析与总结:

经典线段树题目,线段树的成段更新。  


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define mem(str,x) memset(str,(x),sizeof(str))
#define len  (right-left+1)
#define mid  ((left+right)>>1)
#define lson rt<<1,left,m
#define rson rt<<1|1,m+1,right
using namespace std;
typedef long long int64;
const int MAXN = 100005;
int64 sum[MAXN<<2], col[MAXN<<2];

inline void push_up(int rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
inline void push_down(int rt,int _len){
    if(col[rt]){
        int l = rt<<1, r = rt<<1|1, m = _len>>1;
        col[l] += col[rt]; col[r] += col[rt];
        sum[l] += col[rt] * (_len-m);
        sum[r] += col[rt] * m;
        col[rt] = 0;
    }
}
void build(int rt,int left,int right){
    col[rt] = 0;
    sum[rt] = 0;
    if(left==right){
        scanf("%lld", &sum[rt]);
        col[rt] = 0;
        return;
    }
    int m = mid;
    build(lson);
    build(rson);
    push_up(rt);
}
void update(int rt,int left,int right,int l,int r,int add){
    if(l<=left && right<=r){
        col[rt] += add;
        sum[rt] += add*len;
        return;
    }
    push_down(rt,len);
    int m = mid;
    if(l <= m) update(lson,l,r,add);
    if(r > m) update(rson,l,r,add);
    push_up(rt);
}
int64 query(int rt,int left,int right,int l,int r){
    if(left==l && right==r)return sum[rt];
    push_down(rt,len);
    int m = mid;
    if(r <= m) return query(lson,l,r);
    else if(l > m) return query(rson,l,r);
    else return query(lson,l,m)+query(rson,m+1,r);
}

int main(){
    int n,m,a,b,c;
    char cmd[3];
    while(~scanf("%d%d",&n,&m)){
        build(1,1,n);
        for(int i=0; i<m; ++i){
            scanf("%s",cmd);
            if(cmd[0]=='C'){
                scanf("%d%d%d",&a,&b,&c);
                update(1,1,n,a,b,c);
            }
            else{
                scanf("%d%d",&a,&b);
                printf("%lld\n",query(1,1,n,a,b));
            }
        }
    }
    return 0;
}


 ——  生命的意义,在于赋予它意义士。

          原创 http://blog.csdn.net/shuangde800 , By   D_Double  (转载请标明)



你可能感兴趣的:(poj 3468 A Simple Problem with Integers(线段树|成段更新,区间查询))