nyoj 116 士兵殺敵二

2021-06-27 15:51:41 字數 2197 閱讀 3421

描述

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

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

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

輸入

只有一組測試資料

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

隨後的一行是n個整數,ai表示第i號士兵殺敵數目。(0<=ai<=100)

隨後的m行每行是一條指令,這條指令包含了乙個字串和兩個整數,首先是乙個字串,如果是字串query則表示南將軍進行了查詢操作,後面的兩個整數m,n,表示查詢的起始與終止士兵編號;如果是字串add則後面跟的兩個整數i,a(1<=i<=n,1<=a<=100),表示第i個士兵新增殺敵數為a.

輸出對於每次查詢,輸出乙個整數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

const int max = (1<<21);  

//深度:求對數,取大於結果的那個數再+1.移位,知道深度以後直接左移就可以求出最大結點數。

struct

node[max]; //dai

int a, s[1000003];

void creat(int i, int left, int right)

creat(i*2, left, (left+right)/2);

creat(i*2+1, (left+right)/2+1, right);

node[i].sum = node[2*i].sum + node[2*i+1].sum; }

void print(int i)

void query(int x, int y, int i)

mid = (node[i].l + node[i].r)/2;

if(x > mid)

query(x, y, 2*i+1);

else if(y <= mid)

query(x, y, 2*i);

else

}void add(int i, int x, int y)

int main()

else if(c[0] == 'a')

}return 0; }

還有可以用樹狀陣列來做.

樹狀陣列實際上還是乙個陣列,只不過它的每個元素儲存了跟原來陣列的一些元素相關的結合值。

若a為原陣列,定義陣列c為樹狀陣列。c陣列中元素c[ i ]表示a[ i –lowbit( i ) + 1]至a[ i ]的結合值。樹狀陣列要注意的一點就是lowbit是個什麼東西.根據樹狀陣列的資料結構圖可發現,每個節點的轄區為2^k, 其中k就是這個點編號二進位制末尾0的個數.  

所以lowbit(x)= x&(-x), 正是這個節點編號與編號的反+1進行與運算。2^k就等於lowbit(x)。

這樣一來,如果想更新某個節點的值,並且把包含這個點所有節點值都更新,那麼用樹狀陣列就很方便了。

假設某個點為pos, 那麼這個點的直接父節點就是pos+lowbit(pos),一層一層地向上更新就可以了。

求和的話,從pos開始,(c陣列表示某幾個點的和,但c[6]並不是前6個數的和,而是樹狀陣列特有的結構,只是5,6兩個數的和),s+=pos, 然後pos進行更新。就是加上小於pos的其他兄弟節點的c值。。(說不太清了,看圖說話比較好懂,總之就是樹狀陣列的特殊結構決定了它的一些特殊性質,而這些特殊性質剛好使它在更新節點方面比較方便)。

樹狀陣列:

#include

int c[1000005], n;

int lowbit(int x)

void modify(int pos, int v)

} int sum(int pos)

return s; }

int main()

while(m--)

else if(que[0] == 'q')

}return 0; }

NYOJ 116 士兵殺敵(二)

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

NYOJ 116 士兵殺敵 二

樹狀陣列已經看了好幾天了,一直都是半懂半不懂,實在是忍無可忍了,今天晚上又看了看劉汝佳的 似乎明白了樹狀陣列到底是怎麼回事,果斷寫篇部落格,明天要把線段樹和字典樹給搞定,不能再肉了 樹狀陣列可以很方便的查詢任意區間內所有元素的和,還可以對樹進行修改,時間複雜度位log n 有兩個很重的陣列,a n ...

NYOJ 116 士兵殺敵(二)

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