poj 3486 A Simple Problem with Integers(树状数组第三种模板改段求段)

简介:
/*
    树状数组第三种模板(改段求段)不解释! 
       不明白的点这里:here!
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 100005
using namespace std;

typedef long long LL;

LL ss[N], B[N], C[N];

int n, m;

void addB(int x, int k){//B[i]表示被1...i整体一共加了多少的总和 
    for(int i=x; i<=n; i+=i&(-i))  B[i]+=x*k; 
}

void addC(int x, int k){//1....x节点的每个节点的增量 
    for(int i=x; i>0; i-=i&(-i))   C[i]+=k;
}

LL sumB(int x){
    LL s=0;
    for(int i=x; i>0; i-=i&(-i)) s+=B[i];
    return s;
}

LL sumC(int x){//x节点总共的增量 
    LL s=0;
    for(int i=x; i<=n; i+=i&(-i)) s+=C[i];
    return s;
}

LL sum(int x){
    return x==0 ? 0 : sumC(x)*x + sumB(x-1); 
}

void update(int a, int b, int c){
    addB(b, c);
    addC(b, c);
    if(a-1>0){
        addB(a-1, -c); 
        addC(a-1, -c);
    }
}

int main(){
    int m;
    while(scanf("%d%d", &n, &m)!=EOF){
        for(int i=1; i<=n; ++i){
            scanf("%lld", &ss[i]);
            ss[i]+=ss[i-1];
        } 
        char ch[2];
        int a, b, c;
        while(m--){
            scanf("%s", ch); 
            if(ch[0]=='Q'){
                scanf("%d%d", &a, &b);
                printf("%lld\n", ss[b]-ss[a-1]+sum(b)-sum(a-1));
            }
            else{
                scanf("%d%d%d", &a, &b, &c);
                update(a, b, c); 
            }
        }
    }
    return 0;
}









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3969029.html,如需转载请自行联系原作者
目录
相关文章
|
开发框架 .NET
poj 3468 A Simple Problem with Integers线段树区间修改
题目意思很简单,有N个数,Q个操作, Q l r 表示查询从l到r 的和,C l r v 表示将从l到r 的值加上v,明显的线段树,不知道线段树的人肯定暴力,肯定超时,哈哈!!
33 0
PAT (Advanced Level) Practice 1044 Shopping in Mars (前缀和 二分)
PAT (Advanced Level) Practice 1044 Shopping in Mars (前缀和 二分)
96 0
|
Java
HDOJ/HDU 1297 Children’s Queue(推导~大数)
HDOJ/HDU 1297 Children’s Queue(推导~大数)
139 0
|
存储 测试技术
HDOJ(HDU) 2523 SORT AGAIN(推导排序、、)
HDOJ(HDU) 2523 SORT AGAIN(推导排序、、)
102 0
|
人工智能 Java