zoukankan      html  css  js  c++  java
  • 线段树

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

    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
    ",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;
    }
    
  • 相关阅读:
    sublime使用及插件
    Unity 查找
    Unity 3D 的四种坐标系
    C#知识点<4>
    C#知识点<3>
    C#知识点<2>
    排序算法
    OOP的三大特性------封装、继承、多态
    C#常用函数
    C++-------------类和对象
  • 原文地址:https://www.cnblogs.com/liuyongliu/p/10295370.html
Copyright © 2011-2022 走看看