P3374 【模板】树状数组 1(单点增减,区间求和)

本文详细介绍了一种高效的数据结构——树状数组,并通过一个具体的编程问题实例来讲解其使用方法。文章首先介绍了树状数组的基本概念,接着通过一个涉及单点更新与区间查询的操作示例,展示了树状数组在解决此类问题时的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 P3374 【模板】树状数组 1

题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某一个数加上x

2.求出某区间每一个数的和

输入输出格式

输入格式:

 

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x k 含义:将第x个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

 

输出格式:

 

输出包含若干行整数,即为所有操作2的结果。

 

输入输出样例

输入样例#1:
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
输出样例#1:
14
16

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=10000,M<=10000

对于100%的数据:N<=500000,M<=500000

样例说明:

故输出结果14、16

 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int N = 500100 ;
 5 
 6 int n,m,a;
 7 int ch,x,y,v;
 8 int sum[N];//树状数组 
 9 
10 int lowbit(int x)         
11 {
12     return x&(-x);
13 }
14 
15 void update(int p,int v)    //将第P个数增加v 
16 {
17     while(p<=n)
18     {
19         sum[p] += v;
20         p += lowbit(p);  
21     }    
22 } 
23  
24 int query(int p)    //查询第p个点的值是多少 
25 {
26     int ans=0;
27     while(p)
28     {
29         ans += sum[p];
30         p -= lowbit(p);
31     }
32     return ans;
33 }
34 
35 int main()
36 {
37     ios::sync_with_stdio(false) ;  //输入输出优化 
38     cin>>n>>m;
39     for (int i=1;i<=n;i++) 
40     {
41         cin>>a;
42         update(i,a);  //建树 
43     }
44     for (int i=1;i<=m;++i) 
45     {
46         cin>>ch;
47         if (ch==1)        //单点修改 
48         {
49             cin>>x>>y;
50             update(x,y);
51         }
52         if (ch==2)        //区间查询
53         {
54             cin>>x>>y;            
55             cout<<query(y)-query(x-1)<<endl; 
56         } 
57     }
58     return 0;
59 }

 

转载于:https://www.cnblogs.com/mjtcn/p/6831291.html

# P5524 [Ynoi2012] NOIP2015 充满了希望 ## 题目描述 给一个长为 $n$ 的序列,有 $m$ 个操作,操作编号从 $1$ 到 $m$,每个操作为: `1 x y`:将序列位置为 $x,y$ 的两个元素交换。 `2 l r x`:将序列区间 $[l,r]$ 内所有元素修改为 $x$。 `3 x`:查询序列 $x$ 位置的值。 现在有 $q$ 次查询,每次查询给出一个操作的区间 $[l,r]$: 先将序列中的元素全部置为 $0$,之后依次进行从 $l$ 到 $r$ 的所有操作,求出所有这些操作中所有 $3$ 操作的答案的和。 查询之间独立。 ## 输入格式 第一行三个数表示 $n,m,q$。 之后 $m$ 行,每行 $2$ 到 $4$ 个数,依次表示每个操作。 之后 $q$ 行,每行两个数 $l,r$,查询依次进行 $[l,r]$ 的所有操作,所有 $3$ 操作的答案的和。 ## 输出格式 对于每次查询,输出一行一个数表示答案。 ## 输入输出样例 #1 ### 输入 #1 ``` 5 10 6 3 1 3 5 2 5 5 10 3 1 2 5 5 5 3 5 3 1 1 1 5 2 5 5 3 3 5 5 6 3 6 1 10 2 8 3 10 7 8 ``` ### 输出 #1 ``` 5 5 8 5 8 0 ``` ## 说明/提示 Idea:nzhtl1477&ccz181078,Solution:nzhtl1477&ccz181078,Code:ccz181078,Data:ccz181078 对于 $10\%$ 的数据,满足 $1\le n,m,q\le 1000$。 对于 $40\%$ 的数据,满足 $1\le n,m,q\le 10^5$。 对于另外 $20\%$ 的数据,没有 $1$ 操作。 对于另外 $20\%$ 的数据,没有 $2$ 操作。 对于 $100\%$ 的数据,满足 $1\le n,m,q\le 10^6$,$1\le x\le 10^9$。 求C++线段树解法
最新发布
05-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值