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