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

原创粉丝点击