秋实大哥与线段树 UESTC - 1073

墨蓝 2022-06-14 10:39 196阅读 0赞

秋实大哥与线段树 UESTC - 1073


Problem

“学习本无底,前进莫徬徨。” 秋实大哥对一旁玩手机的学弟说道。

秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构。

为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作。

秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值;一种是询问一段区间的和。

Input

第一行包含一个整数nn,表示序列的长度。

接下来一行包含nn个整数aiai,表示序列初始的元素。

接下来一行包含一个整数mm,表示操作数。

接下来mm行,每行是以下两种操作之一:

1 x v : 表示将第x个元素的值改为v
2 l r : 表示询问[l,r]这个区间的元素和
1≤n,m,v,ai≤1000001≤n,m,v,ai≤100000,1≤l≤r≤n1≤l≤r≤n。

Output

对于每一个22 ll rr操作,输出一个整数占一行,表示对应的答案。

Sample Input

3
1 2 3
3
2 1 2
1 1 5
2 1 2

Sample Output

3
7

ps:线段树

代码如下:

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. typedef long long ll;
  5. const int maxn = 100000+100;
  6. ll a[maxn];
  7. int n, m;
  8. inline ll lowbit(int x) {
  9. return x&(-x);
  10. }
  11. inline void updata(int x, int p) {
  12. while(x <= n) {
  13. a[x] += p;
  14. x += lowbit(x);
  15. }
  16. }
  17. inline ll sum(int x) {
  18. ll res = 0;
  19. while(x) {
  20. res += a[x];
  21. x -= lowbit(x);
  22. }
  23. return res;
  24. }
  25. int main() {
  26. scanf("%d", &n);
  27. for(int i = 1; i <= n; i++) {
  28. ll x;
  29. scanf("%lld", &x);
  30. updata(i, x);
  31. }
  32. scanf("%d", &m);
  33. for(int i = 0; i < m; i++) {
  34. ll b, x, y;
  35. scanf("%lld %lld %lld", &b, &x, &y);
  36. if(b == 1){
  37. ll p = sum(x) - sum(x-1);
  38. updata(x, -p);
  39. updata(x, y);
  40. }
  41. else {
  42. printf("%lld\n",sum(y) - sum(x-1));
  43. }
  44. }
  45. return 0;
  46. }

发表评论

表情:
评论列表 (有 0 条评论,196人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线段

    线段树入门: 转载博客:[点击打开链接][Link 1] 前几天开始接触线段树,其一些基本的操作还是很容易理解的,但是区间更新我着实理解了好一会(因该是本人太菜),今天有时

    相关 线段

    一 概述 线段树,类似区间树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(l