線段樹的應用之敵兵布陣

2021-09-11 01:27:25 字數 1494 閱讀 7181

首先讓我們先來了解一下什麼是線段樹 

線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。

使用線段樹可以快速的查詢某乙個節點在若干條線段**現的次數,時間複雜度為o(logn)。而未優化的空間複雜度為2n,實際應用時一般還要開4n的陣列以免越界,因此有時需要離散化讓空間壓縮。

對於線段樹中的每乙個非葉子節點[a,b],它的左兒子表示的區間為[a,(a+b)/2],右兒子表示的區間為[(a+b)/2+1,b]。因此線段樹是平衡二叉樹,最後的子節點數目為n,即整個線段區間的長度。

基本結構

線段樹是建立**段的基礎上,每個結點都代表了一條線段[a,b]。長度為1的線段稱為元線段。非元線段都有兩個子結點,左結點代表的線段為[a,(a + b) / 2],右結點代表的線段為[((a + b) / 2)+1,b]。

下圖就是兩棵長度範圍為[1,5][1,10]的線段樹。

長度範圍為[1,l] 的一棵線段樹的深度為log (l) + 1。這個顯然,而且儲存一棵線段樹的空間複雜度為o(l)。

線段樹支援最基本的操作為插入和刪除一條線段。下面以插入為例,詳細敘述,刪除類似。

將一條線段[a,b] 插入到代表線段[l,r]的結點p中,如果p不是元線段,那麼令mid=(l+r)/2。如果bmid,那麼將線段[a,b] 也插入到p的右兒子結點中。

插入(刪除)操作的時間複雜度為o(logn)。

用於要大量用到輸入輸出,最好用scanf來進行資料的輸入 

#include #include #includeusing namespace std;

struct sd;

#define n 50003

int camp[n],ans;

sd tree[4*n];

void build(int index,int left,int right)

else

}void quiry(int index,int left,int right)

else

else

else}}

}void add(int x,int data,int index)

mid=(tree[index].left+tree[index].right)/2;

if(x>mid)add(x,data,index*2+1);

else add(x,data,index*2);

}int t,n;

int main()

build(1,1,n);

cout<

int ii,jjj;

while(scanf("%s",a)&&a[0]!='e')

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

else if(a[0]=='s')}}

return 0;

}

線段樹 A敵兵布陣

include stdio.h include cstdio include algorithm using namespace std define inf 0x3f3f3f3f const int max n 1e5 10 int a max n int b max n 1 void init ...

敵兵布陣 線段樹

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

敵兵布陣 線段樹

敵兵布陣 time limit 1000msmemory limit 32768kb64bit io format i64d i64u submit status description c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿...