浏览器标题切换
浏览器标题切换end

信奥一本通-树状数组模版题目-修改数列元素+求子数列元素和

复制代码
给定n个数列,规定有两种操作,一是修改某个元素,二是求子数列[a,b]的连续和。数列的元素个数最多10万个,询问操作最多10万次。

 
输入
第一行2个整数n,m(n表示输入n个数,m表示有m个操作)
第二行输入n个数列。
接下来m行,每行有三个数k,a,b(k=0表示求子数列[a,b]的和;k=1表示第a个数加b)。

 
输出
输出若干行数字,表示k=0时,对应的子数列[a,b]的连续和。


样例输入
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8
 

样例输出
11
30
35
 
复制代码

 

模板题。信奥p211

记住三步操作:求lowbit、对某个元素进行加法操作、查询某个前缀和。

复制代码
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 const int N=1e5+10;
 8 int n,c[N];
 9 
10 int lowbit(int x)
11 {
12     return x&(-x);
13 }
14 
15 void update(int x,int k)//在第x个位置(数)上加上k,并在树状数组中修改相应元素//对某个元素进行加法操作
16 {
17     while(x<=n)
18     {
19         c[x]+=k;
20         x+=lowbit(x);
21     }
22 }
23 
24 int sum(int x)//查询前缀和
25 {
26     int res=0;
27     while(x>0)
28     {
29         res+=c[x];
30         x-=lowbit(x);
31     }
32     return res;
33 }
34 
35 int main()
36 {
37     int m,k;
38     scanf("%d %d",&n,&m);
39     for(int i=1; i<=n; i++)
40     {
41         scanf("%d",&k);
42         update(i,k);
43     }
44     for(int i=1; i<=m; i++)
45     {
46         int kk,a,b;
47         scanf("%d %d %d",&kk,&a,&b);
48         if(kk==0)//求区间和且输出
49         {
50             int ans=sum(b)-sum(a-1);
51             printf("%d\n",ans);
52         }
53         else if(kk==1)//把第a个位置的元素更改为b
54             update(a,b);
55     }
56     return 0;
57 }
复制代码

 

posted @   抓水母的派大星  阅读(300)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示