1. 程式人生 > >樹狀數組求區間和 和 單點更新

樹狀數組求區間和 和 單點更新

i++ const 一個數 數列 個數 輸出 表示 void 數字

題目描述

如題,已知一個數列,你需要進行下面兩種操作:

1.將某一個數加上x

2.求出某區間每一個數的和

輸入輸出格式

輸入格式:

第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。

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

接下來M行每行包含3個整數,表示一個操作,具體如下:

操作1: 格式:1 x k 含義:將第x個數加上k

操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和

輸出格式:

輸出包含若幹行整數,即為所有操作2的結果。

輸入輸出樣例

輸入樣例:

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4

輸出樣例:

14
16

說明

時空限制:1000ms,128M

數據規模:

對於30%的數據:N<=8,M<=10

對於70%的數據:N<=10000,M<=10000

對於100%的數據:N<=500000,M<=500000

#include<iostream>
#include<string.h>
using namespace std;
const int maxn=500000+5;
const int maxm=500000+5;
int c[maxn];//用於存儲對應下標所存儲的數據和
int lowbit(int x)
{
    return x&(-x);
}
void updata(int
x,int y)//下標為x的c[x] 加上y { while(x<maxn) { c[x]+=y; x+=lowbit(x); } } void query(int x ,int y) { int sum1=0,sum2=0; while(x>0) { sum1+=c[x]; x-=lowbit(x); } while(y>0) { sum2+=c[y]; y-=lowbit(y); } cout<<sum2-sum1<<endl; }
int main() { memset(c,0,sizeof(c)); int n,m,v; int t,x,y; cin>>n>>m; for(int i=1;i<=n;i++) { cin>>v; updata(i,v); } for(int i=1;i<=m;i++) { cin>>t>>x>>y; if(t==1) { updata(x,y); } else { query(x-1,y); } } return 0; }

樹狀數組求區間和 和 單點更新