zoukankan      html  css  js  c++  java
  • 【模板】树状数组

    luogu-P3374 【模板】树状数组 1

    luogu-P3368 【模板】树状数组 2

    在这里稍微总结一下(luogu)上树状数组的两个模板。

    稍微提一嘴(update())(query())的遍历次序。

    (update())中$ x+=lowbit() $相当于每次加上从右往左数的(第一个(1)到最右边)的值,比如(1(1))(2(10))(4(100))(8(1000))

    (query())中$ x-=lowbit() $相当于每次减去从右往左数的(第一个(1)到最右边)的值,比如(5(101))(4(100))0(000)

    单点修改,区间求和
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 500010;
    
    int n, m, tr[N];
    
    int lowbit(int x) {
        return x & (-x);
    }
    
    void update(int x, int k) {
        for (; x <= n; x += lowbit(x)) 
            tr[x] += k;
    }
    
    int query(int x) {
        int res = 0;
        for (; x; x -= lowbit(x)) 
            res += tr[x];
        return res;
    }
    
    void build() {
        for (int i = 1; i <= n; i++) {
            int a; cin >> a; update(i, a);
        }
    }
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n >> m;
        build();
        while (m--) {
            int d, a, b; cin >> d >> a >> b;
            if (d == 1) update(a, b);
            else cout << (query(b) - query(a - 1)) << endl;
        }
        return 0;
    }
    
    单点求值,区间修改
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 500010;
    
    int n, m;
    int tr[N];
    
    int lowbit(int x) {
        return x & (-x);
    }
    
    void updata(int x, int k) {
        for (; x <= n; x += lowbit(x)) tr[x] += k;
    }
    
    void build() {
        int now = 0, last = 0;
        for (int i = 1; i <= n; i++) {
            cin >> now; updata(i, now - last); last = now; //构造差分数组tr,使用树状数组维护
        }
    }
    
    int query(int x) {
        int ans = 0;
        for (; x; x -= lowbit(x)) ans += tr[x];
        return ans;
    }
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin >> n >> m;
        build();
        while (m--) {
            int d; cin >> d;
            if (d == 1) {
                int x, y, k; cin >> x >> y >> k;
                updata(x, k); updata(y + 1, -k); //对区间[x,y]进行修改,只用修改tr[x]与tr[y+1]:
            } else {
                int x; cin >> x;
                cout << query(x) << endl; //查询第x个数则将tr[1]~tr[x]累加
            }
        }
        return 0;
    }
    
  • 相关阅读:
    PHP与WCF第一次亲密接触
    PHP操作MongoDB
    如何用SVN进行个人版本管理
    【Android】还原“微信”apk中的“发现”和“我”两个模块
    使php支持mbstring库
    mysql 与 mysqli的区别
    nginx 配置正向 HTTP 代理服务器[转]
    正向代理与反向代理的区别【Nginx读书笔记】
    为什么要使用Nginx?
    【转】关于HTTP中文翻译的讨论
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/13697259.html
Copyright © 2011-2022 走看看