标签:
#include<stdio.h> const int M = 1e5 ; int a[M] , c[M]; int n , m ; void modify (int x , int add ) { for (; x <= n ; x += x & (-x)) c[x] += add ; } int sum_get (int x) { int ret = 0 ; for (; x > 0 ; x -= x & (-x)) ret += c[x] ; return ret ; } /* void modify (int x , int y , int add)//二维 { for (; x <= n ; x += x & (-x)) { for (; x <= n ; y += y & (-y)) { c[x][y] += add ; } } } int get_sum (int x , int y ) { int ret = 0 ; for (; x > 0 ; x -= x & (-x)) { for (; y > 0 ; y -= y & (-y)){ ret += c[x][y] ; } } return ret ; } */ int main () { freopen ("a.txt" , "r" , stdin ) ; scanf ("%d%d" , &n , &m) ; for (int i = 1 ; i <= n ; i ++) { scanf ("%d" , &a[i]) ; modify (i , a[i]) ; } while (m --) { int x ; scanf ("%d" , &x) ; printf ("%d\n" , sum_get (x)) ; } return 0 ; }
杰哥跟我讨论了一下为何树状数组如此神奇:
经过观察,你可以发现,2(10) , 4(100) ,8(1000) , 16(10000)……(2进制) 这种点,都指的是1~n所有的数。
那么像5(101) , 6(110),7(111)……这类代表着什么区间呢?
5:5(101)~5 (101)
6:5(101)~6(110)
7:7(111)~7(111)
所以类推一下89(1001101):65(1000001)~80(10010000),81(10010001)~88(1001100),89(1001101)
所以对于一个数统治了那些区域就一目了然了。
标签:
原文地址:http://www.cnblogs.com/get-an-AC-everyday/p/4550757.html