线段树啊

来源:互联网 发布:日本年轻人 知乎 编辑:程序博客网 时间:2024/06/11 19:05

from a PPT

【代码】

#include<stdio.h>#define MAXN 10struct 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);elsereturn 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;}


原创粉丝点击