樹狀陣列區間更新
阿新 • • 發佈:2019-01-13
題目描述
如題,已知一個數列,你需要進行下面兩種操作:
1.將某區間每一個數數加上x
2.求出某一個數的值
輸入輸出格式
輸入格式:
第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來M行每行包含2或4個整數,表示一個操作,具體如下:
操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k
操作2: 格式:2 x 含義:輸出第x個數的值
輸出格式:
輸出包含若干行整數,即為所有操作2的結果。
輸入輸出樣例
輸入樣例#1: 複製
5 5 1 5 4 2 3 1 2 4 2 2 3 1 1 5 -1 1 3 5 7 2 4
輸出樣例#1: 複製
6 10
說明
時空限制:1000ms,128M
資料規模:
對於30%的資料:N<=8,M<=10
對於70%的資料:N<=10000,M<=10000
對於100%的資料:N<=500000,M<=500000
樣例說明:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int b[500100],n,c[500100]; int lowbit(int i)//樹狀陣列嘗龜操作 { return i&(-i); } void change(int i,int num) { while(i<=n) { b[i]+=num; i+=lowbit(i); } return ; } int sum(int i) { int ans=0; while(i>0) { ans+=b[i]; i-=lowbit(i); } return ans; } int main() { int m,x; scanf("%d %d",&n,&m); int a=0; memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { scanf("%d",&c[i]);//輸入資料 change(i,c[i]-a); a=c[i]; } for(int i=1;i<=m;i++) { int d,x,y,k; scanf("%d",&d); if(d==1) { scanf("%d %d %d",&x,&y,&k);//修改區間 change(x,k); change(y+1,-k); } else { scanf("%d",&x); int ans; ans=sum(x);//單點查詢 printf("%d \n",ans); } } return 0; }