首先讓我們先來了解一下什麼是線段樹
線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。
使用線段樹可以快速的查詢某乙個節點在若干條線段**現的次數,時間複雜度為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國在海岸線沿...