線段樹 HDU1166敵兵布陣

2022-05-24 10:03:08 字數 1831 閱讀 4351

這個是線段樹中最入門的題目,但是由於不了解線段樹的概念,當然更不知道怎麼樣,所以覺得挺費勁,整了一會發現還是基本的思想,就是還是將乙個線段繼續分割,一直分割到不能分割,這道題目是知道多少個軍營,也就是區間為1-n, 將它分割, 建立樹, 可以不用儲存它區間的左端點和右端點,用陣列下標代表就可以了, 陣列的值代表當前軍營裡人的個數,然後這個題就是單個點的增加或者減少,其實增加減少都是增加,減少只是把增加的數目變成負數就行了,還有就是更新完最下面的點還要一直往上更新。那樣查詢區間的時候才不會出錯。下面是**的實現

1 #include 2 #include 3

4const

int max = 50010 * 4;5

int segment[max];//

存放線段樹,因為類似完全二叉樹, 所以可以用陣列來表示6//

更新root節點的值,即兵營裡的人數

7void pushup(int root)811

//建樹,只需要兩個點,乙個起點,乙個終點

12void buildtree(int root, int left, int

right)

1320

int mid = (left + right) / 2

;21 buildtree(root * 2

, left, mid);

22 buildtree(root * 2 + 1, mid + 1

, right);

23//

調整它的上面節點的值

24pushup(root);25}

26/*

更新最下面節點的值,而且要更新以上給他有關聯的節點的值, root代表根節點,

27pos代表更新的位置, add_num 代表增加的值,如果是負數,說明是減少的,left和right

28分別為當前節點區間的左右端點

*/29

void update(int root, int pos, int add_num, int left, int

right)

3036

int mid = (left + right) / 2;37

if (pos <=mid)

38 update(root * 2

, pos, add_num, left, mid);

39else

40 update(root * 2 + 1, pos, add_num, mid + 1

, right);

41//

向上調整

42pushup(root);43}

44//

獲取指定區間內的總數

45int getsum(int root, int left, int right, int l, int

r)46

51int mid = (l + r) / 2;52

int res = 0;53

//如果在當前節點的右半個區間內

54if(left >mid)

5558

//如果在當前節點的左半個區間內

59else

if(right <=mid)

6063

//乙個在左邊,乙個在右邊

64else

6569

return

res;70}

7172

intmain()

7394

else

if(op[0] == 's'

)9598else

99102

}103

}104

return0;

105 }

線段樹 hdu1166 敵兵布陣

problem description c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的...

敵兵布陣 HDU 1166 線段樹

c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的一清二楚,每個工兵營地的人數都有可能發生...

敵兵布陣 HDU 1166(線段樹)

c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的一清二楚,每個工兵營地的人數都有可能發生...