codevs树状数组基础练习

 

 

 

 

 

题目描述

一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

 

输入描述

输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

 

输出描述

对于每个询问2都单独一行打印出所求的区间和

codevs树状数组基础练习_第1张图片

本来此题是线段树基础练习,但我更倾向于采用树状数组来解决。

树状数组的实现由采取结构体版,也有采取函数版,第一步是构建这样一个树状数组的模型。在此采用开辟一个较大的静态数组来创建一个线段树。利用add操作将数据填入树中。这个add操作也是解决题目中询问1的操作。

codevs树状数组基础练习_第2张图片

lowbit函数表示的是2^k,k值为i的二进制的最低位的连续的0的个数。在树状数组中有一下规律:

 

 C[1]=A[1];

C[2]=A[1]+A[2];

C[3]=A[3];

 C[4]=A[1]+A[2]+A[3]+A[4];

C[5]=A[5];

C[6]=A[5]+A[6];

C[7]=A[7];

C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

对照式子可以发现  C[i]=A[i-2^k+1]+A[i-2^k+2]+......A[i]; (k为i的二进制中从最低位到高位连续零的长度)例如i=8时,k=3;

从这就可以清除lowbit函数的含义了。

对于询问2是求数组内指定区间内元素的和,使用sum函数实现codevs树状数组基础练习_第3张图片

 

 

 

你可能感兴趣的:(ACM水题)