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;
}