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

    转载请注明出处:http://blog.csdn.net/a1dark

    学了一段时间的线段树、始终没有没有形成自己的风格、于是重头再来一遍、以HH大牛的线段树分类、单点更新、成段更新、区间合并、扫描线、重新梳理一遍自己的线段树知识、   

    单点更新:【HDU 1166 敌兵布阵】

    分析:单点更新还是挺容易的、就是建立一颗二叉树、用来表示区间、可以优化查询时间和更新时间、

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    const int maxn=55555;
    struct segmentTree{
        int sum;
    }tree[maxn<<2];
    int per[maxn];
    void PushUp(int rt){
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void build(int l,int r,int rt){
        if(l==r){
            tree[rt].sum=per[l];
            return;
        }
        int mid=(l+r)/2;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void update(int x,int add,int l,int r,int rt){
        if(l==r){
            tree[rt].sum+=add;
            return;
        }
        int mid=(l+r)/2;
        if(x<=mid)update(x,add,lson);
        else update(x,add,rson);
        PushUp(rt);
    }
    int query(int a,int b,int l,int r,int rt){
        if(a<=l&&b>=r){
            return tree[rt].sum;
        }
        int ans=0;
        int mid=(l+r)/2;
        if(a<=mid) ans+=query(a,b,lson);
        if(b>mid) ans+=query(a,b,rson);
        return ans;
    }
    int main(){
        int t,n,cas=1;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            printf("Case %d:
    ",cas++);
            for(int i=1;i<=n;i++){
                scanf("%d",&per[i]);
            }
            build(1,n,1);
            char op[11];
            while(scanf("%s",op)!=EOF){
                if(strcmp(op,"End")==0)break;
                if(strcmp(op,"Query")==0){
                    int a,b;
                    scanf("%d%d",&a,&b);
                    printf("%d
    ",query(a,b,1,n,1));
                }
                else if(strcmp(op,"Add")==0){
                    int a,b;
                    scanf("%d%d",&a,&b);
                    update(a,b,1,n,1);
                }
                else if(strcmp(op,"Sub")==0){
                    int a,b;
                    scanf("%d%d",&a,&b);
                    update(a,-b,1,n,1);
                }
            }
        }
        return 0;
    }


    成段更新:【HDU 1698 Just a Hook】

    分析:成段更新稍微复杂一点、其实也就是多个延迟标记、一次不更新到底、为什么不更新到底呢、还不是为了节约时间、等到下次需要向下更新或者查询的时候、就向下更新、这样貌似复杂度要低许多、

    #include<stdio.h>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define maxn 100005
    struct segmentTree{
        int sum;
        int col;
    }tree[maxn<<2];
    void PushUp(int rt){
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void build(int l,int r,int rt){
        tree[rt].col=0;
        if(l==r){
            tree[rt].sum=1;
            return;
        }
        int mid=(l+r)/2;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void PushDown(int rt,int len){
        if(tree[rt].col){
            tree[rt<<1].col=tree[rt<<1|1].col=tree[rt].col;
            tree[rt<<1].sum=(len-len/2)*tree[rt].col;
            tree[rt<<1|1].sum=(len/2)*tree[rt].col;
            tree[rt].col=0;
        }
    }
    void update(int a,int b,int c,int l,int r,int rt){
        if(a<=l&&b>=r){
            tree[rt].col=c;
            tree[rt].sum=c*(r-l+1);
            return;
        }
        PushDown(rt,r-l+1);
        int mid=(l+r)/2;
        if(a<=mid)update(a,b,c,lson);
        if(b>mid)update(a,b,c,rson);
        PushUp(rt);
    }
    int main(){
        int t,n,m,cas=1;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            build(1,n,1);
            scanf("%d",&m);
            int a,b,v;
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&a,&b,&v);
                update(a,b,v,1,n,1);
            }
            printf("Case %d: The total value of the hook is %d.
    ",cas++,tree[1].sum);
        }
        return 0;
    }
    


    区间合并:待续


  • 相关阅读:
    深入理解sizeof
    trie树详解
    高精度计算
    编写高效的Android代码
    Android Architecture
    AIDL Android中的远程接口
    性能测试常见术语
    软件与软件测试相关
    注解实现Springmvc+jsp步骤
    非注解实现SpringMvc+JSP (一般用不到 主要用于了解研究底层)
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3402648.html
Copyright © 2011-2022 走看看