ACM-线段树
来源:互联网 发布:关于大学生网络的论文 编辑:程序博客网 时间:2024/06/05 06:54
#include <iostream>using namespace std;#define MAXN 100struct Node{ int left,right,mid; int cover;//表示给数据是否存在}seg_tree[4*MAXN];//数组一般开到4倍长度void build(int l,int r,int num)//l,r为当前结点的左右端点,num为结点在数组中的编号{ cout<<num<<" "<<l<<" "<<r<<endl; seg_tree[num].left=l; seg_tree[num].right=r; seg_tree[num].mid=(l+r)/2; seg_tree[num].cover=0; if(l+1!=r)//若不是叶子结点 { build(l,seg_tree[num].mid,2*num); build(seg_tree[num].mid,r,2*num+1); }}void insert(int l,int r,int num){ if(seg_tree[num].left==l&&seg_tree[num].right==r) { //若插入的线段树完全覆盖当前结点所表示的线段 seg_tree[num].cover=1; //cout<<num<<endl; 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); }}bool del(int l,int r,int num){ if(seg_tree[num].left+1==seg_tree[num].right) { //删除到叶结点的情况 int f = seg_tree[num].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;//子结点置1 seg_tree[2*num+1].cover=1;//子结点置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);}