ACwing 1264. 动态求连续区间和
树状树组操作:
(1)求区间[i,j]的连续和
(2)第i个数增加k
来源:ACwing算法课
树状树组模板:
int lowbit(int x){
return x&(-x);
}
第x个数加上c
void add(int x,int c){
for(int i=x;i<N;i+=lowbit(i)){
t[i]+=c;
}
}
注意循环到树状数组的最大值。
查询区间[1,x]的和:
int ask(int x){
int sum=0;
for(int i=x;i>=1;i-=lowbit(i))sum+=t[i];
return sum;
}
注意:x不能是小于1的整数
注意:如果查询区间[x,最后)的和ask(N-1)-ask(x-1)
java代码:
import java.io.*;
import java.util.*;
class Main{
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static final int N=200010;
static int n,m;
static int[]a=new int[N];
static int[]t=new int[N];
static int lowbit(int x){
return x&(-x);
}
static void add(int x,int k){
for(int i=x;i<=n;i+=lowbit(i))t[i]+=k;
}
static int ask(int x){
int sum=0;
for(int i=x;i!=0;i-=lowbit(i))sum+=t[i];
return sum;
}
public static void main(String[]args)throws IOException{
String[]str=br.readLine().split(" ");
n=Integer.parseInt(str[0]);
m=Integer.parseInt(str[1]);
String[]s=br.readLine().split(" ");
for(int i=1;i<=n;i++){
a[i]=Integer.parseInt(s[i-1]);
}
//搭建树状树组
for(int i=1;i<=n;i++){
add(i,a[i]);
}
//
for(int i=1;i<=m;i++){
s=br.readLine().split(" ");
int k=Integer.parseInt(s[0]);
int x=Integer.parseInt(s[1]);
int y=Integer.parseInt(s[2]);
if(k==0){
System.out.println(ask(y)-ask(x-1));
}else{
add(x,y);
}
}
}
}