• 序列 [线段树]


    序列

    在这里插入图片描述


    color{red}{正解部分}

    使用 线段树 维护 bb, 初值为 bi-b_i, 每次修改时, 若一个位置上的值变为了 00, 则说明其会对答案产生新的贡献,
    在外部使用 树状数组 将贡献计入答案, 然后将该位置的值 重置为 bi-b_i, 重置的时间复杂度是 O(logN)O(log N) .

    考虑最坏情况, 每次操作 [1,N][1, N],
    这样 bi=1b_i=1 的位置最多重置 NNbi=2b_i=2 最多重置 N2frac{N}{2} 次, bi=3b_i=3 最多 …

    所以总共需要 重置 O(NlogN)O(N log N) 次, 总时间复杂度 O(Nlog2N)O(N log^2 N) .


    color{red}{实现部分}

    重置 可以在 修改 时 使用 update()update() 实现 .

    #include<bits/stdc++.h>
    #define reg register
    #define fi first
    #define se second
    typedef std::pair<int, int> pr;
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 100005;
    const int inf = 0x3f3f3f3f;
    
    int N;
    int M;
    int Tmp_1;
    int B[maxn];
    
    struct Bit_Tree{
            int v[maxn], lim;
            void Add(int k, int x){ while(k<=lim)v[k]+=x,k+=k&-k; }
            int Query(int k){ if(k<=0)return 0; int s=0; while(k)s+=v[k],k-=k&-k; return s; }
    } bit_t;
    
    struct Segment_Tree{
    
            struct Node{ int l, r, t, max_v, id; } T[maxn << 2];
    
            void Push_down(const int &k){ 
                    T[k].max_v += T[k].t;
                    if(T[k].l == T[k].r) return T[k].t = 0, void();
                    T[k<<1].t += T[k].t, T[k<<1|1].t += T[k].t, T[k].t = 0;
            }
    
            void Push_up(const int &k){
                    if(T[k<<1].t) Push_down(k<<1);
                    if(T[k<<1|1].t) Push_down(k<<1|1);
                    T[k].max_v = std::max(T[k<<1].max_v, T[k<<1|1].max_v); 
                    if(T[k<<1].max_v == T[k].max_v) T[k].id = k<<1;
                    else T[k].id = k<<1|1;
            }
    
            void Build(int k, int l, int r){
                    T[k].l = l, T[k].r = r; if(l == r) return T[k].max_v = B[l], T[k].id = k, void();
                    int mid = l+r >> 1; Build(k<<1, l, mid), Build(k<<1|1, mid+1, r); Push_up(k);
            }
    
            void update(int k){
                    int l = T[k].l, r = T[k].r;
                    if(T[k].t) Push_down(k);
                    if(l == r) return bit_t.Add(l, 1), T[k].max_v=B[l], void();
                    update(T[k].id); Push_up(k);
            }
    
            void Modify(int k, const int &ql, const int &qr, const int &aim){
                    int l = T[k].l, r = T[k].r;
                    if(T[k].t) Push_down(k);
                    if(r < ql || l > qr) return ;
                    if(ql <= l && r <= qr){
                            T[k].t += aim, Push_down(k); 
                            while(!T[k].max_v) update(k);
                            return ;
                    }
                    Modify(k<<1, ql, qr, aim), Modify(k<<1|1, ql, qr, aim); Push_up(k);
            }
    
            int Query(int k, const int &ql, const int &qr){
                    int l = T[k].l, r = T[k].r;
                    if(T[k].t) Push_down(k);
                    if(r < ql || l > qr) return -inf;
                    if(ql <= l && r <= qr) return T[k].max_v;
                    return std::max(Query(k<<1, ql, qr), Query(k<<1|1, ql, qr));
            }
    
    } seg_t;
    
    int main(){
            N = read(), M = read();
            for(reg int i = 1; i <= N; i ++) B[i] = -read();
            seg_t.Build(1, 1, N); bit_t.lim = N;
            for(reg int i = 1; i <= M; i ++){
                    int opt = read(), l = read(), r = read();
                    if(opt == 2) printf("%d
    ", bit_t.Query(r) - bit_t.Query(l-1));
                    else seg_t.Modify(1, l, r, 1);
            }
            return 0;
    }
    
  • 相关阅读:
    黄聪:Delphi 中的 XMLDocument 类详解(6) 访问节点属性
    黄聪:Delphi 中的 XMLDocument 类详解(8) 添加与删除节点
    黄聪:Delphi 中的 XMLDocument 类详解(15) 创建与保存 xml
    黄聪:Delphi 中的 XMLDocument 类详解(9) 关于 HasChildNodes 与 IsTextElement
    黄聪:Delphi 中的 XMLDocument 类详解(4) 获取根目录下的元素数
    黄聪:Delphi 中的 XMLDocument 类详解(14) 遍历 XML 文件
    黄聪:Delphi 中的 XMLDocument 类详解(13) 关于 XML 属性
    黄聪:Delphi 中的 XMLDocument 类详解(3) 读取 xml 文件
    黄聪:Delphi 中的 XMLDocument 类详解(20) 动态建立 XMLDocument 对象
    黄聪:Delphi 中的 XMLDocument 类详解(5) 获取元素内容
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822420.html
Copyright © 2020-2023  润新知