南陽 116 士兵殺敵(二) 樹狀陣列

2021-06-19 18:04:59 字數 2897 閱讀 6894

時間限制:

1000 ms  |  記憶體限制:

65535 kb

難度:5 描述

南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。

小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。

南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候,需要考慮到新增的殺敵數。

輸入

只有一組測試資料

第一行是兩個整數n,m,其中n表示士兵的個數(1

輸出對於每次查詢,輸出乙個整數r表示第m號士兵到第n號士兵的總殺敵數,每組輸出佔一行

樣例輸入

5 6

1 2 3 4 5

query 1 3

add 1 2

query 1 3

add 2 3

query 1 2

query 1 5

樣例輸出

688

20

**:
#include #define lowbit(x) x&(-x)

int a[1000001]=,b;

void add(int i, int x)

}int sum(int m)

return sum;

}int main()

while (m--)

return 0;

}

樹狀陣列基礎知識(引自別人的成果):
如果給定乙個陣列,要你求裡面所有數的和,一般都會想到累加。但是當那個陣列很大的時候,累加就顯得太耗時了,時間複雜度為o(n),並且採用累加的方法還有乙個侷限,那就是,當修改掉陣列中的元素後,仍然要你求陣列中某段元素的和,就顯得麻煩了。所以我們就要用到樹狀陣列,他的時間複雜度為o(lgn),相比之下就快得多。下面就講一下什麼是樹狀陣列:一般講到樹狀陣列都會少不了下面這個圖:

下面來分析一下上面那個圖看能得出什麼規律:據圖可知:c1=a1,c2=a1+a2,c3=a3,c4=a1+a2+a3+a4,c5=a5,c6=a5+a6,c7=a7,c8=a1+a2+a3+a4+a5+a6+a7+a8,c9=a9,c10=a9+a10,c11=a11........c16=a1+a2+a3+a4+a5+.......+a16。

分析上面的幾組式子可知,當 i 為奇數時,ci=ai ;當 i 為偶數時,就要看 i 的因子中最多有二的多少次冪,例如,6 的因子中有 2 的一次冪,等於 2 ,所以 c6=a5+a6(由六向前數兩個數的和),4 的因子中有 2 的兩次冪,等於 4 ,所以 c4=a1+a2+a3+a4(由四向前數四個數的和)。

(一)有公式:cn=a(n-a^k+1)+.........+an(其中 k 為 n 的二進位制表示中從右往左數的 0 的個數)。

那麼,如何求 a^k 呢?求法如下:

?

intlowbit(intx)

lowbit()的返回值就是 2^k 次方的值。

求出來 2^k 之後,陣列 c 的值就都出來了,接下來我們要求陣列中所有元素的和。

(二)求陣列的和的演算法如下:

(1)首先,令sum=0,轉向第二步;

(2)接下來判斷,如果 n>0 的話,就令sum=sum+cn轉向第三步,否則的話,終止演算法,返回 sum 的值;

(3)n=n - lowbit(n)(將n的二進位制表示的最後乙個零刪掉),回第二步。

**實現:

?

intsum(intn)

returnsum;

}

(三)當陣列中的元素有變更時,樹狀陣列就發揮它的優勢了,演算法如下(修改為給某個節點 i 加上 x ):

(1)當 i<=n 時,執行下一步;否則的話,演算法結束;

(2)ci=ci+x ,i=i+lowbit(i)(在 i 的二進位制表示的最後加零),返回第一步。

**實現:

?

voidchange(inti,intx)

}

nyoj 116 士兵殺敵(二) 樹狀陣列

時間限制 1000 ms 記憶體限制 65535 kb 難度 5 描述 南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候...

NYOJ 題116 士兵殺敵(二)樹狀陣列

時間限制 1000 ms 記憶體限制 65535 kb 難度 5 輸入只有一組測試資料 第一行是兩個整數n,m,其中n表示士兵的個數 1輸出 對於每次查詢,輸出乙個整數r表示第m號士兵到第n號士兵的總殺敵數,每組輸出佔一行 樣例輸入 5 6 1 2 3 4 5 query 1 3 add 1 2 q...

(樹狀陣列)NYOJ116 士兵殺敵(二)

傳送門 nyoj116 士兵殺敵 二 描述 南將軍手下有n個士兵,分別編號1到n,這些士兵的殺敵數都是已知的。小工是南將軍手下的軍師,南將軍經常想知道第m號到第n號士兵的總殺敵數,請你幫助小工來回答南將軍吧。南將軍的某次詢問之後士兵i可能又殺敵q人,之後南將軍再詢問的時候,需要考慮到新增的殺敵數。輸...