NYoj 116士兵殺敵(二)區間求和,單點更新

2022-01-19 20:38:14 字數 1743 閱讀 7862

時間限制: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和上個**求區間最大值改為區間和即可,這裡注意的是節點數要開成4*葉子節點。(原因:剛好存滿n個節點的線段樹有趨近於2n個節點,而為了防溢位,要建出第n+1個葉子節點,那麼根節點要再開一大棵子樹出來,所以是4n)

其實就是等比數列求和,當第n層為n+1個節點時,總和就是4倍,n就是兩倍。可參考:

#include using

namespace

std;

const

int maxnode = (1e6)*4+10

;const

int max = 1e6+10

;struct

node node[maxnode];

int father[max];//

葉子節點的編號

void buildtree(int i,int left,int

right)

buildtree(i

<<1,left,(int)(floor(left+right)/2.0

)); buildtree((i

<<1)+1,(int)(floor(left+right)/2.0+1

),right);}//

向上更新,更新所有區間和,傳入乙個加乙個

void updatetree(int ri,int

vl)

node[ri].value +=vl;

updatetree(ri/2

,vl);

//int fi = ri/2;

//int a = node[fi<<1].value;

//int b = node[(fi<<1)+1].value;

//node[fi].value = a + b;

//updatetree(ri/2);

}int

sum;

//查詢從上向下查詢

void query(int i,int l,int

r)

//兒子左子樹

i = i<<1

;

//分段分割求

if(l <=node[i].right)

//右子樹

i++;

if(r >=node[i].left)

}int

main()

string

op;

inta,b;

while(m--)

else

}return0;

}

NYOJ 116 士兵殺敵(二)

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

NYOJ 116 士兵殺敵 二

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

nyoj 116 士兵殺敵二

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