线段树

浅谈线段树
线段树详解(非递归实现)
线段树与树状数组的区别,作者:闵梓轩

demo
/***********************************************/
int n,a[maxn+2],m;
 
struct node{
    int l,r;
    int h;
}tree[4*maxn+5];
 
void build(int l,int r,int k)
{
    tree[k].l=l;tree[k].r=r;tree[k].h=0;
    if(l!=r)//未到叶子节点
    {
        int mid=(l+r)/2;
        build(l,mid,2*k);//左孩子
        build(mid+1,r,2*k+1);//右
    }
}
 
void update(int l,int r,int k,int p)//区间修改,从头遍历,k记录此时遍历位置
{
    int L,R;
    if(r<tree[k].l || l>tree[k].r) return ;
    else if(l<=tree[k].l && r>=tree[k].r)//修改区间全包含tree
    {
        L=tree[k].l;
        R=tree[k].r;
         
    }
    else if(l>tree[k].l && r<=tree[k].r)//全被包含
    {
        L=l;
        R=r;
    }
    else if(l<tree[k].l && r<tree[k].r) //左交
    {
        L=tree[k].l;
        R=r;
    }
    else if(r>tree[k].r && l>tree[k].l)//右交
    {
        L=l;
        R=tree[k].r;
    }
     
    tree[k].h+=(abs(R-L)+1)*p;
    if(tree[k].l==tree[k].r) return ;
    update(l,r,2*k,p);
    update(l,r,2*k+1,p);
}
 
void update1(int x,int k,int p)//单点修改
{
    if(x>=tree[k].l && x<=tree[k].r)
    {
        tree[k].h+=p;
        int mid=(tree[k].l+tree[k].r)/2;
        if(x<=mid) update1(x,2*k,p);
        else update1(x,2*k+1,p);
    }
    if(tree[k].r==tree[k].l) return ;
}
 
 
void ask1(int k,int p)//单点查询
{
    if(tree[k].l==tree[k].r && tree[k].r==p) printf("%d\n",tree[k].h);
    else {
        int mid=(tree[k].l+tree[k].r)/2;
        if(p<=mid) ask1(2*k,p);
        else ask1(2*k+1,p);
    }
}
 
 
int ans=0;
void ask(int l,int r,int k)//区间查询
{
    if(tree[k].l>=l && tree[k].r<=r) ans=max(ans,tree[k].h);
    else
    {
        int mid=(tree[k].l+tree[k].r)/2;
        if(!(l>mid || r<tree[k].l)) ask(l,r,2*k);
        if(!(r<mid+1 || l>tree[k].r)) ask(l,r,2*k+1);
    }
}
 
int main()
{
    c_2(n,m);
    build(1,n,1);
    for(int i=1;i<=n;i++) cin>>a[i],update1(i,1,a[i]);//此处a[i]可以在build时就加入,更高效
    for(int i=1;i<=m;i++)
    {
        int op,x,y,k;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y>>k;
            update(x,y,1,k);
        }
        else
        {
            cin>>x;
            ans=0;
            ask1(1,x);
            //cout<<ans<<endl;
        }
        //update(l,r,1,1);
    }
    //cout<<tree[1].h<<endl;
    return 0;
}
posted @ 2019-01-20 16:47  liuyongliu  阅读(122)  评论(0)    收藏  举报