zkw线段树模板题

学了zkw线段树,觉得没什么必要刷专题的吧(切不动啊)。。

那先放一个模板题吧(我绝不会和你说搬了一道树状数组模板题的!!!)

题目描述

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

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

 

解法:zkw线段树(模板)

code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1500005;
 6 int n,m,Q,a[N];
 7 inline int read() {
 8     int x=0,f=1; char ch=getchar();
 9     while (ch<'0'||ch>'9') f=(ch=='-')?-1:1,ch=getchar();
10     while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
11     return x*f;
12 }
13 void B() {
14     for (m=1; m<=n+1; m<<=1);
15     for (int i=m; i<=m+n-1; i++) scanf("%d",&a[i]);
16     for (int i=m-1; i; i--) a[i]=a[i<<1]+a[i<<1|1];
17 }
18 void U(int x,int v) {
19     a[m+x-1]+=v;
20     for (int i=(m+x-1)>>1; i; i>>=1) a[i]=a[i<<1]+a[i<<1|1];
21 }
22 int A(int l,int r) {
23     int ret=0;
24     for (l=m+l-2,r=m+r; l^r^1!=0; l>>=1,r>>=1) {
25         if (!(l&1)) ret+=a[l^1];
26         if (r&1) ret+=a[r^1];
27     }
28     return ret;
29 }
30 int main() {
31     n=read(),Q=read(),B();
32     for (int i=1; i<=Q; i++) {
33         int t=read(),x=read(),y=read();
34         if (t&1) U(x,y); else printf("%d\n",A(x,y));
35     }
36     return 0;
37 }
View Code

 

zkw线段树特别清真。。

转载于:https://www.cnblogs.com/whc200305/p/7588088.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值