一些區間有關的問題,給一些區間線段求並區間的長度或並區間個數當資料範圍過大時會讓時間複雜度過高不滿足解題時間的要求。此時需要一種高效的資料結構來幫助我們。線段樹正是這樣的工具,它借助分而治之的思想解決子問題,再將子問題的解組合起來。有關線段樹的各種操作函式均用遞迴函式實現:
struct nodeseg_tree[3*maxn]; // 設定根節點下標是1,則左孩子是2*dex,右孩子下標是2*dex+1.
void build(int l,int r,int num)
void insert(int l,int r,int num)
if(r<=seg_tree[num].mid)insert(l,r,2*num);
else if(l>=seg_tree[num].mid)insert(l,r,2*num+1);
else
}void del(int l,int r,int num)
else if(seg_tree[num].cover)
if(rseg_tree[num].mid)del(l,r,2*num+1);
else
}int cal(int num)
例題:hdu 1166 敵兵布陣
題意:詳見
#include #include#includeusing namespace std;
const int maxn=5e4+5;
int n,x[maxn];// 最長區間長度
struct nodebtree[3*maxn]; // 設定根節點下標是1,左孩子是2*dex,右孩子下標是2*dex+1.
void build(int root,int l,int r)
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
btree[root].sum=btree[2*root].sum+btree[2*root+1].sum; //遞迴回溯賦值給雙親結點
}void update(int root,int pos,int val)
int mid=(btree[root].left+btree[root].right)/2;
if(pos<=mid)update(2*root,pos,val);
else update(2*root+1,pos,val);
btree[root].sum=btree[root*2].sum+btree[2*root+1].sum;
}int query(int root,int l,int r)
int main(int argc, char *argv)
build(1,1,n);
printf("case %d:\n",t);
while(~scanf("%s",str)&&strcmp(str,"end"))
t++;
}return 0;
}
線段樹 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國都掌握的一清二楚,每個工兵營地的人數都有可能發生...