• 线段树总结


    转载请注明出处: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;
    }
    


    区间合并:待续


  • 相关阅读:
    Android系统进程Zygote启动过程的源代码分析
    Android系统默认Home应用程序(Launcher)的启动过程源代码分析
    Android应用程序安装过程源代码分析
    Android应用程序进程启动过程的源代码分析
    Android应用程序绑定服务(bindService)的过程源代码分析
    Android应用程序发送广播(sendBroadcast)的过程分析
    Android应用程序注册广播接收器(registerReceiver)的过程分析
    Android系统中的广播(Broadcast)机制简要介绍和学习计划
    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:
    解开Android应用程序组件Activity的"singleTask"之谜
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3402648.html
Copyright © 2020-2023  润新知