士兵殺死(兩)(南陽116)

2021-09-07 02:32:43 字數 2202 閱讀 3445

時間限制:

1000 ms  |  記憶體限制:

65535 kb

難度:5

描寫敘述

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

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

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

輸入

僅僅有一組測試資料

第一行是兩個整數n,m,當中n表示士兵的個數(1(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

士兵殺敵(一) 陣列是固定的,所以能夠用乙個sum陣列來儲存每乙個元素的和即可,可是不能每次都加,由於那樣會超時。查詢次數太多。可是這個士兵殺敵(二)就不能用那個方法來解了,由於這個是動態的,中間元素的值可能會變化。所以引出乙個新的東西來。剛開始想了一下,實在是沒有想到方法,就去討論區看了看,一看好像都說用樹狀陣列,就去找樹狀陣列的使用方法。

先上圖。看著**釋easy理解點。

陣列a是原陣列中的元素。陣列c是樹狀陣列中的元素,圖中c陣列的元素組成為a中的某些元素之和,這些元素的個數取決於它的下標能被多少個2整除,像c[1] = a[1]; c[2] = a[1] + a[2]; c[3] = a[3]; c[4] = a[1] + a[2] + a[3] + [4] = c[2] + c[3]; ……這些個數能夠寫乙個通式c[i] = a[n - 2^k + 1] + ……+a[i]; 當中k為 i 的二進位制中從右往左數的 0 的個數 ,就像6有乙個, 6能夠寫成 2 × 3, 所以c[6] = a[5] + a[6]; 所以能夠定義乙個函式來求這個數.

6的二進位制為0110

5的二進位制為0101

6^5 = 0011

6&(6^5) = 0010 = 十進位制中的2

所以函式能夠這麼寫

int lowbit(int n)//

求n中有多少個能被2的多少次冪整除的。即2^k, 也就是樹狀陣列的作用域

也能夠寫成

int lowbit(int n)//

求n中有多少個能被2的多少次冪整除的,即2^k, 也就是樹狀陣列的作用域

更改乙個數的值, 就要更改次數在樹狀陣列中的全部祖先,只是這個時間複雜度是o(logn); 以下是更改值(加入殺敵數)的函式

void add(int pos, int num)//

加入新值到樹狀陣列中

}

以下就是求和函式。 由於這樣的方法之所以快。是求他的最小樹根節點的和, 最小樹的個數為當前要求的n的二進位制中為1的個數。即展開式中能寫成不同2的冪指數的項數。

比如: 15 = 2^3 + 2^2 + 2^1 + 2^0; 所以n = 15時, 最小數有四個。求和的時間複雜度為o(logn); 

int sum(int n)//

求前n個數的和

return

sum;

}

關鍵就是這三步, 這三步搞明確了,基本上就不成問題了。可是。當時依照 殺敵(一) 中的思維。還統計了乙個總數,那樣不會快,反而會慢,所以直接求即可。以下是完整的**

#include#includeint a[1000010];

int n,m;

int lowbit(int n)//求n中有多少個能被2的多少次冪整除的。即2^k, 也就是樹狀陣列的作用域

void asd(int i,int m)//加入新值到樹狀陣列中

}int sum(int n)//求前n個數的和

return sum;

}int main()

while(m--)

return 0;

}

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

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

南陽oj116 士兵殺敵(二) 線段樹

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

南陽OJ116 士兵殺敵(二)(線段樹)

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