C语言-算法-树状数组

统计和

题目描述

给定一个长度为 n ( n ≤ 100000 ) n(n\leq 100000) n(n100000),初始值都为 0 0 0 的序列, x ( x ≤ 100000 ) x(x\leq 100000) x(x100000) 次的修改某些位置上的数字,每次加上一个数,然后提出 y ( y ≤ 100000 ) y(y\leq 100000) y(y100000) 个问题,求每段区间的和。

输入格式

第一行 1 1 1 个整数,表示序列的长度 n n n

第二行 1 1 1 个整数,表示操作的次数 w w w

后面依次是 w w w 行,分别表示加入和询问操作。

其中,加入用 x 表示,询问用 y 表示。

x x x的格式为 x a b 表示在序列上第 a a a 个数加上 b b b。保证 1 ≤ a ≤ n 1 \leq a \leq n 1an 1 ≤ b ≤ 1 0 9 1 \leq b \leq 10^9 1b109

y y y 的格式为 y a b 表示询问 a a a b b b 区间的加和。保证 1 ≤ a ≤ b ≤ n 1 \leq a \leq b \leq n 1abn

输出格式

每行一个正整数,分别是每次询问的结果

样例 #1

样例输入 #1

5
4
x 3 8
y 1 3
x 4 9
y 3 4

样例输出 #1

8
17

代码

#include 
int lowbit(int x); // 返回x的最低位的1对应的值
void update(int x, int v, int n); // 更新操作,将第x个位置加上v
long long getsum(int x); // 查询前x个数的和
#define MAXN 100010
long long c[MAXN]; // 树状数组

int main() {
    int n, w, x, y;
    char op[2];
    scanf("%d %d", &n, &w); // 序列长度和操作次数
    while(w--)
    {
        scanf("%s %d %d", op, &x, &y);
        if(op[0] == 'x')
        {
            update(x, y, n);
        }
        else
        {
            printf("%lld\n", getsum(y) - getsum(x - 1));
        }
    }
    return 0;
}

int lowbit(int x) // 返回x的最低位的1对应的值
{
    return x & -x;
}

void update(int x, int v, int n) // 更新操作,将第x个位置加上v
{
    for(int i = x; i <= n; i += lowbit(i))
    {
        c[i] += v;
    }
}

long long getsum(int x) // 查询前x个数的和
{
    long long sum = 0;
    for(int i = x; i > 0; i -= lowbit(i))
    {
        sum += c[i];
    }
    return sum;
}

你可能感兴趣的:(算法,c语言,数据结构)