ACwing 1264. 动态求连续区间和

【树状树组】树状树组模板_i++

树状树组操作:

(1)求区间[i,j]的连续和

(2)第i个数增加k 

【树状树组】树状树组模板_开发语言_02

 来源: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);
            }
            
        }
    }
}