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

      线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。

    对于线段树中的每一个非叶子节点[o],若其表示的区间为[l,r],它的左儿子表示的区间为[l,mid],右儿子表示的区间为[mid+1,r]。因此线段树是平衡二叉树,最后的子节点数目为n,即整个线段区间的长度。

      使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logn)。而未优化的空间复杂度为4n,因此有时需要离散化让空间压缩。

      线段树可以支持的操作可分为两种:单点修改和区间修改

    建树操作(单点修改与区间修改通用)

    void build(int l,int r,int o)
    {
        if(l==r){scanf("%d",&sum[o]);return;}
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
        sum[o]=sum[o<<1]+sum[o<<1|1];
    }

    单点修改,区间查询:

    int update(int pre,int val,int l,int r,int o)
    {
        if(l==r) {sum[o]+=val;return;}
        int mid=(l+r)>>1;
        if(pre<=mid) update(pre,val,lson);
        else update(pre,val,rson);
        sum[o]=sum[o<<1]+sum[o<<1|1]
    }
    int query(int L,int R,int l,int r,int o)
    {
        if(L<=l&&r<=R) return sum[o];
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid) ans+=query(L,R,lson);
        if(R> mid) ans+=query(L,R,rson);
        return ans;
    }

      在区间修改的时候,如果我们一个一个点的去修改那么复杂度将会变得很高,这时候我们就要用到一个叫懒标记(lazy tag)的东西,若整个区间都要修改,就将该区间改变后的值算出来,给它打上一个标记,若日后要查询区间中的一段,或修改区间中的一段再将其展开

    void pushdown(int lnum,int rnum,int o)
    {
        if(lazy[o])
        {
            sum[o<<1]+=lnum*lazy[o];
            sum[o<<1|1]+=rnum*lazy[o];
            lazy[o<<1]+=lazy[o];
            lazy[o<<1|1]+=lazy[o];
            lazy[o]=0;
        }
    }
    void update(int L,int R,int v,int l,int r,int o)//添加 
    {
        if(L<=l&&r<=R) {lazy[o]+=v;sum[o]+=v*(r-l+1);return;}
        int mid=(l+r)>>1;
        pushdown(mid-l+1,r-mid,o);
        if(L<=mid) update(L,R,v,lson);//
        if(R> mid) update(L,R,v,rson);//
        sum[o]=sum[o<<1]+sum[o<<1|1];//更新
    }
    int query(int L,int R,int l,int r,int o)//查询 
    {
        if(L<=l&&r<=R) return sum[o];
        int mid=(l+r)>>1,ans=0;
        pushdown(mid-l+1,r-mid,o);
        if(L<=mid) ans+=query(L,R,lson);//
        if(R> mid) ans+=query(L,R,rson);//
        return ans;
    }
  • 相关阅读:
    C#解压或压缩文件夹
    C#文件帮助类FoderHelper
    C#数据库帮助类SqlHelper
    非常有意思的程序猿数据比較
    hdu1066
    【SICP练习】149 练习4.5
    【spring+websocket的使用】
    Android Studio 使用正式签名进行调试
    基于空间直方图meanshift跟踪
    Intel为Google的物联网平台Brillo推出开发板Edison
  • 原文地址:https://www.cnblogs.com/cold-cold/p/9991486.html
Copyright © 2011-2022 走看看