• [kuangbin]线段树


    [kuangbin]线段树

    2019.07.08

    1.HDU 1166 敌兵布阵

    1.1题目描述

    ​ 单点修改+区间查询

    1.2代码

    #include <cstdio>
    #include <iostream>
    #define mid ((tr[d].l + tr[d].r) >> 1)
    #define sl d*2
    #define sr d*2+1
    using namespace std;
    const int N = 50005;
    int T,n;
    int a[N];
    string Q;
    struct Tree{
        int l,r;
        int sum;
    }tr[N*8];
    
    void build(int d,int l,int r){
        tr[d].l = l,tr[d].r = r;
        if (l == r){
            tr[d].sum = a[l];
            return;
        }
        build(sl,l,mid);
        build(sr,mid+1,r);
        tr[d].sum = tr[sl].sum + tr[sr].sum;
    }
    
    void modify(int d,int x,int w){
        if (tr[d].l == x && tr[d].r == x){
            tr[d].sum += w;
            return;
        }
        if (x <= mid) modify(sl,x,w);
        else modify(sr,x,w);
        tr[d].sum = tr[sl].sum + tr[sr].sum;
    }
    
    int query(int d,int l,int r){
        if (tr[d].l == l && tr[d].r == r){
            return tr[d].sum;
        }
        if (r <= mid) return query(sl,l,r);
        else if (l > mid) return query(sr,l,r);
        else return query(sl,l,mid)+query(sr,mid+1,r);
    }
    
    int main(){
        scanf("%d",&T);
        for (int t = 1;t <= T;t++){
            scanf("%d",&n);
            for (int i = 1;i <= n;++i){
                scanf("%d",a+i);
            }
            printf("Case %d:
    ",t);
            build(1,1,n);
            while(cin >> Q && Q != "End"){
                int u,v;
                scanf("%d%d",&u,&v);
                if (Q == "Query"){
                    printf("%d
    ",query(1,u,v));
                }else if (Q == "Add"){
                    modify(1,u,v);
                }else if (Q == "Sub"){
                    modify(1,u,-v);
                }
            }
        }
    }
    

    2.HDU 1754 I Hate It

    2.1 题目描述

    ​ 单点修改+区间查询

    2.2 代码

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #define mid ((tr[d].l + tr[d].r) >> 1)
    #define sl d*2
    #define sr d*2+1
    using namespace std;
    const int N = 200005;
    int m,n,u,v;
    int a[N];
    string Q;
    struct Tree{
        int l,r;
        int max;
    }tr[N*8];
    
    void build(int d,int l,int r){
        tr[d].l = l,tr[d].r = r;
        if (l == r){
            tr[d].max = a[l];
            return;
        }
        build(sl,l,mid);
        build(sr,mid+1,r);
        tr[d].max = max(tr[sl].max,tr[sr].max);
    }
    
    void modify(int d,int x,int w){
        if (tr[d].l == x && tr[d].r == x){
            tr[d].max = w;
            return;
        }
        if (x <= mid) modify(sl,x,w);
        else modify(sr,x,w);
        tr[d].max = max(tr[sl].max,tr[sr].max);
    }
    
    int query(int d,int l,int r){
        if (tr[d].l == l && tr[d].r == r){
            return tr[d].max;
        }
        if (r <= mid) return query(sl,l,r);
        else if (l > mid) return query(sr,l,r);
        else return max(query(sl,l,mid),query(sr,mid+1,r));
    }
    
    int main(){
        while(~scanf("%d%d",&n,&m)){
            for (int i = 1;i <= n;++i){
                scanf("%d",a+i);
            }
            build(1,1,n);
            for (int i = 0;i < m;++i){
                cin >> Q;
                scanf("%d%d",&u,&v);
                if (Q == "Q") printf("%d
    ",query(1,u,v));
                if (Q == "U") modify(1,u,v);
            }
        }
    }
    

    3.POJ 3468 A Simple Problem with Integers

    3.1 题目描述

    ​ 区间修改+区间查询

    3.2 代码

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #define mid ((tr[d].l + tr[d].r) >> 1)
    #define sl (d*2)
    #define sr (d*2+1)
    using namespace std;
    const int N = 100005;
    typedef long long ll;
    int m,n,u,v,w;
    int a[N];
    string Q;
    struct Tree{
        int l,r;
        ll sum,tag;
    }tr[N*8];
    
    int len(int d){
        return (tr[d].r - tr[d].l + 1);
    }
    
    void build(int d,int l,int r){
        tr[d].l = l,tr[d].r = r,tr[d].tag = 0;
        if (l == r){
            tr[d].sum = a[l];
            return;
        }
        build(sl,l,mid);
        build(sr,mid+1,r);
        tr[d].sum = tr[sl].sum + tr[sr].sum;
    }
    
    void pushdown(int d){
        tr[sl].sum += tr[d].tag*len(sl);
        tr[sr].sum += tr[d].tag*len(sr);
        tr[sl].tag += tr[d].tag;
        tr[sr].tag += tr[d].tag;
        tr[d].tag = 0;
    }
    
    void modify(int d,int l,int r,int w){
        if (tr[d].l == l && tr[d].r == r){
            tr[d].sum += w*(r-l+1);
            tr[d].tag += w;
            return;
        }
        pushdown(d);
        if (r <= mid) modify(sl,l,r,w);
        else if (l > mid) modify(sr,l,r,w);
        else {
            modify(sl,l,mid,w);
            modify(sr,mid+1,r,w);
        }
        tr[d].sum = tr[sl].sum + tr[sr].sum;
    }
    
    ll query(int d,int l,int r){
        if (tr[d].l == l && tr[d].r == r){
            return tr[d].sum;
        }
        pushdown(d);
        if (r <= mid) return query(sl,l,r);
        else if (l > mid) return query(sr,l,r);
        else return query(sl,l,mid) + query(sr,mid+1,r);
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for (int i = 1;i <= n;++i) scanf("%d",a+i);
        build(1,1,n);
        for (int i = 1;i <= m;++i){
            cin >> Q;
            if (Q == "Q"){
                scanf("%d%d",&u,&v);
                printf("%lld
    ",query(1,u,v));
            }else if (Q == "C"){
                scanf("%d%d%d",&u,&v,&w);
                modify(1,u,v,w);
            }
        }
        //system("pause");
        return 0;
    }
    

    4. POJ 2528 Mayor's posters

    4.1题目描述

    ​ 区间修改+区间查询+离散化

    4.2 题解

    (1 <= l_i <= r_i <= 10000000) 需要离散化处理,同时如果离散化之后两个相邻点之间差大于1,需要在其中间插入一个点以确保不影响统计。

    ​ 离散化之前点数为2*N,离散化之后再算上插入的点,最多可达4*N。

    4.3 代码

    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #define mid ((tr[d].l + tr[d].r) >> 1)
    #define ls (d << 1)
    #define rs ((d << 1) | 1)
    using namespace std;
    const int N = 40005;
    int T,n,m;
    int l[N],r[N],hash[N];
    struct Tr{
        int l,r,w;
    }tr[N*4];
    int ans;
    bool vis[N];
    void build(int d,int l,int r){
        tr[d].l = l,tr[d].r = r,tr[d].w = -1;
        if (l == r){
            return;
        }
        build(ls,l,mid);
        build(rs,mid+1,r);
    }
    
    void pushdown(int d){
        if (tr[d].w == -1) return;
        tr[ls].w = tr[rs].w = tr[d].w;
        tr[d].w = -1;
    }
    
    void modify(int d,int l,int r,int w){
        if (tr[d].l == l && tr[d].r == r){
            tr[d].w = w;
            return;
        }
        pushdown(d);
        if (r <= mid) modify(ls,l,r,w);
        else if (l > mid) modify(rs,l,r,w);
        else {
            modify(ls,l,mid,w);
            modify(rs,mid+1,r,w);
        }
    
    }
    
    void query(int d,int l,int r){
        if (tr[d].w != -1){
            if (!vis[tr[d].w]){
                ans++;
                vis[tr[d].w] = 1;
            }
            return ;
        }
        if (tr[d].l == tr[d].r) return;
        pushdown(d);
        query(ls,l,mid);query(rs,mid+1,r);
    }
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            memset(vis,0,sizeof(vis));
            for (int i = 0;i < n;++i){
                scanf("%d%d",l+i,r+i);
                hash[i*2] = l[i],hash[i*2+1] = r[i];
            }
            sort(hash,hash+2*n);
            m = unique(hash,hash+2*n) - hash;
            int tmpM = m;
            for (int i = 1;i < tmpM;++i){
                if (hash[i] - hash[i-1] > 1){
                    hash[m++] = hash[i-1] + 1;
                }
            }
            sort(hash,hash+m);
            build(1,0,m-1);
            for (int i = 0;i < n;++i){
                l[i] = lower_bound(hash,hash+m,l[i]) - hash;
                r[i] = lower_bound(hash,hash+m,r[i]) - hash;
                modify(1,l[i],r[i],i);
            }
            ans = 0;
            query(1,0,m-1);
            printf("%d
    ",ans);
    
        }
        return 0;
    }
    
  • 相关阅读:
    企业如何实现数字化跃进
    看阿里Alibaba/IOCgolang有感
    WunderGraph 组件
    dremio 增量反射处理
    几个不错的数据加速工具
    citus 11 参考简单使用
    citus 11 的一些参考资料
    kuwala 开源构建分析工作流开发的无代码数据平台
    cube.js 配置json schema
    amass OWASP开源的深入的攻击面映射和资产发现工具
  • 原文地址:https://www.cnblogs.com/mizersy/p/12296511.html
Copyright © 2020-2023  润新知