from a PPT
【代碼】
#include<stdio.h>
#define MAXN 10
struct node
{
int left,right,mid;
int cover;
};
node seg_tree[3*MAXN];
/*
由樹的性質可知,建樹所需的空間大概是所需處理最長線段
長度的2倍多,所以需要開3倍大小的數組.
不懂的說...
*/
void make(int l,int r,int num)
{
//l,r分別爲當前節點的左右端點,num爲節點在數組中的編號.
seg_tree[num].left=l;
seg_tree[num].right=r;
seg_tree[num].mid=(l+r)/2;
if((l+1)!=r)
{
//若不爲葉子節點,則遞歸的建立左右樹
make(l,seg_tree[num].mid,2*num);
make(seg_tree[num].mid,r,2*num+1);
}
}
void insert(int l,int r,int num)
{
//l,r分別爲插入當前節點線段的左右端點,num爲節點在數組中的編號.
if(seg_tree[num].left==l&&seg_tree[num].right==r)
{
//若插入的線段完全覆蓋當前節點所表示的線段
seg_tree[num].cover=1;
return ;
}
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
{
//插入的線段跨越了當前節點所代表線段的中點
insert(l,seg_tree[num].mid,2*num);
insert(seg_tree[num].mid,r,2*num+1);
}
}
int del(int l,int r,int num)//原爲bool
{
if(seg_tree[num].left+1==seg_tree[num].right)
{
//刪除到葉節點的情況
int f=seg_tree[num].cover;//cover??
seg_tree[num].cover=0;
return f;
}
if(seg_tree[num].cover==1)
{
//當前節點不爲葉節點且被覆蓋
seg_tree[num].cover=0;
seg_tree[2*num].cover=1;
seg_tree[2*num+1].cover=1;
}
if(r<=seg_tree[num].mid)
return del(l,r,2*num);
else if(l>=seg_tree[num].mid)
return del(l,r,2*num+1);
else
return del(l,seg_tree[num].mid,2*num)&&del(seg_tree[num].mid,r,2*num+1);
}
int cal(int num)
{
if(seg_tree[num].cover)
return seg_tree[num].right-seg_tree[num].left+1;
if(seg_tree[num].left+1==seg_tree[num].right)
//當遍歷到葉節點時返回
return 0;
return cal(2*num)+cal(2*num+1);
}
int main()
{
int l=1,r=10,num=1;
make(l,r,num);
insert(2,9,1);
printf("%d\n",cal(5));
return 0;
}