給定n個數列,規定有兩種操做,一是修改某個元素,二是求子數列[a,b]的連續和。數列的元素個數最多10萬個,詢問操做最多10萬次。 輸入 第一行2個整數n,m(n表示輸入n個數,m表示有m個操做) 第二行輸入n個數列。 接下來m行,每行有三個數k,a,b(k=0表示求子數列[a,b]的和;k=1表示第a個數加b)。 輸出 輸出若干行數字,表示k=0時,對應的子數列[a,b]的連續和。 樣例輸入 10 5 1 2 3 4 5 6 7 8 9 10 1 1 5 0 1 3 0 4 8 1 7 5 0 4 8 樣例輸出 11 30 35
模板題。信奧p211ios
記住三步操做:求lowbit、對某個元素進行加法操做、查詢某個前綴和。數組
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 using namespace std; 7 const int N=1e5+10; 8 int n,c[N]; 9 10 int lowbit(int x) 11 { 12 return x&(-x); 13 } 14 15 void update(int x,int k)//在第x個位置(數)上加上k,並在樹狀數組中修改相應元素//對某個元素進行加法操做 16 { 17 while(x<=n) 18 { 19 c[x]+=k; 20 x+=lowbit(x); 21 } 22 } 23 24 int sum(int x)//查詢前綴和 25 { 26 int res=0; 27 while(x>0) 28 { 29 res+=c[x]; 30 x-=lowbit(x); 31 } 32 return res; 33 } 34 35 int main() 36 { 37 int m,k; 38 scanf("%d %d",&n,&m); 39 for(int i=1; i<=n; i++) 40 { 41 scanf("%d",&k); 42 update(i,k); 43 } 44 for(int i=1; i<=m; i++) 45 { 46 int kk,a,b; 47 scanf("%d %d %d",&kk,&a,&b); 48 if(kk==0)//求區間和且輸出 49 { 50 int ans=sum(b)-sum(a-1); 51 printf("%d\n",ans); 52 } 53 else if(kk==1)//把第a個位置的元素更改成b 54 update(a,b); 55 } 56 return 0; 57 }