区间求和



问题

 

给出长度为N的数列。数列的初始值是1, 2, 3, …, N。但是这个数列频繁地发生变更,要求出这期间某个连续部分的和。

假设N5的情况。初始为1, 2, 3, 4, 5。在这个情况下,把第3个数字变更为9,第4个数变更为10的话,就会变成1, 2, 9, 10, 5。此时,如果要求第2个数到第5个数的和的话,输出26就可以了。然后,在这个状态下,将第1个数字变更为-5,第三个数变更为5的话,会变成-5, 2, 5, 10, 5,再然后,如果要求第1个数到第3个数的和的话,就是2

请编写解决这种问题的程序。

 

输入

第一行给出整数的个数N(1 ≤ N ≤ 100,000)

第二行给出操作的个数Q(1 ≤ Q ≤ 200,000)

从第三行开始的Q行给出操作的信息。各操作以下面的形式实现。

       · 0 x y:将第x个数变更为y(1 ≤ x ≤ N, -100,000 ≤ y ≤ 100,000)

       · 1 x y:求出从第x个数开始到第y个数为止的和。(1 ≤ x ≤ y ≤ N)

输出

对于操作中以1开头的操作,将求得的值在一行上输出一个。此时要注意答案的范围有可能超过32-bit整数类型的范围。

 

案例输入

5

7

1 2 4

0 3 9

0 4 10

1 2 5

0 1 -5
0 3 5

1 1 3

案例输出

9

26

2

 


#include <stdio.h>

 

#define TMAX 131072

 

long long tree[TMAX * 2 + 3];

 

void set(int x, long long v) {

    x+= TMAX;

   tree[x] = v;

 

   while (x > 1) {

       x /= 2;

       tree[x] = tree[x * 2] + tree[x * 2 + 1];

    }

}

 

long long get(int l, int r) {

   long long ret = 0;

    l+= TMAX;

    r+= TMAX;

 

   while (l <= r) {

       if (l % 2 == 1) {

           ret += tree[l];

           l ++;

       }

       if (r % 2 == 0) {

           ret += tree[r];

           r --;

       }

       l /= 2;

       r /= 2;

    }

   return ret;

}

 

int main() {

   int N;

   scanf( "%d", &N );

   for (int i = 1; i <= N; i ++) {

       set(i, i);

    }

 

   int Q;

   scanf( "%d", &Q );

   while (Q --) {

       int a, b, c;

       scanf( "%d %d %d", &a, &b, &c );

       if (a == 0) {

           set(b, c);

       } else {

           printf( "%lld\n", get(b, c) );

       }

    }

   return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值