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

    本文只总结一下线段树的易错点(毕竟这玩意我早就会了)

    重点:

    • 线段树tag的意义
    • 线段树开4倍空间的意义

    注释里都有。

    update函数任务清单

    • pushdown
    • 递归到子区间
    • pushup

    query函数任务清单

    • pushdown
    • 递归到子区间
    //线段树不能严格开4倍空间, 要开大于等于MAXN的最小2的幂次的4倍空间
    //如:MAXN = 10000, 则要开 16384*4 的空间。
    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long 
    const int MAXN = 550005;
    ll sum[MAXN], tag[MAXN]; 
    //tag表示:这个区间已处理过,但它的子区间还没有。
    void pushdown(ll o, ll l, ll r) {
        ll ls, rs, mid;
        if(tag[o] == 0) return;
        ls = o << 1; rs = ls + 1; mid = (l+r) >> 1;
        sum[ls] += tag[o] * (mid - l + 1);
        sum[rs] += tag[o] * (r - mid);
        tag[ls] += tag[o]; tag[rs] += tag[o];
        tag[o] = 0;
    }
    
    ll query(ll o, ll l, ll r, ll ql, ll qr) {
        pushdown(o, l, r);
    // printf("[%lld,%lld]: %lld
    ", l, r, sum[o]);
        if(ql <= l && r <= qr) {
            return sum[o];
        }
        ll mid = (l+r)>>1, ret = 0, ls, rs;
        ls = o << 1; rs = ls + 1;
        if(ql <= mid) ret += query(ls, l, mid, ql, qr);
        if(qr > mid)  ret += query(rs, mid+1, r, ql, qr);
    printf("%d %d %d ql=%d qr=%d ret= %lld
    ", l, r, sum[o], ql, qr, ret);
    
        return ret;
    }
    void update(ll o, ll l, ll r, ll ql, ll qr, ll v) {
        pushdown(o, l, r);
        ll mid = (l+r)>>1, ls, rs;
        if(ql <= l && r <= qr) {
            sum[o] += (r-l+1) * v;
            tag[o] += v;
            return;
        }
        ls = o << 1; rs = ls + 1;
        if(ql <= mid)  update(ls, l, mid, ql, qr, v);
        if(qr > mid)   update(rs, mid+1, r, ql, qr, v);
        sum[o] = sum[ls] + sum[rs];
    }
    int a[MAXN], n, q;
    signed main(){
        #ifndef ONLINE_JUDGE
        freopen(".in","r",stdin);
        freopen(".out","w", stdout);
        #endif
        scanf("%d %d", &n, &q);
        for(int i = 1; i <= n; i++) {
            ll tmp;
            scanf("%lld", &tmp);
            update(1, 1, n, i, i, tmp);
        }
        for(int i = 1; i <= q; i++) {
            int op, l, r, k;
            scanf("%d%d%d",&op,&l,&r);
            if(op == 1) {
                scanf("%d", &k);
                update(1, 1, n, l, r, k);
            } else {
                printf("%lld
    ", query(1,1,n,l,r));
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    第一章 工欲善其事 必先利其器—Android SDK工具(3)
    UVa 11063
    Remember the Word,LA3942(Trie树+DP)
    Atitit.Gui控件and面板----数据库区-mssql 2008 权限 配置 报表查看成员
    Android手机令牌教程
    cocos2d-x 在mac下执行 demo
    Install Oracle 10g on Red Hat Linux 5.3 Step by Step
    Python根据内嵌的数字将字符串排序(sort by numbers embedded in strings)
    mysql一次运行多个SQL文件
    CentOS/Linux 卸载MATLAB
  • 原文地址:https://www.cnblogs.com/Eroad/p/11856719.html
Copyright © 2011-2022 走看看