线段树与树状数组

爷,独闯天下 提交于 2019-12-03 20:52:50

posted on 2019-10-06 22:08:50

【模板】线段树 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long lld;
int n ,m;
const int N = 1e5 + 5;
lld sum[N << 2], tag[N << 2];
void pushup(int u)
{
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
}
void build(int u, int l, int r)
{
    if(l == r) 
    {
        cin >> sum[u];
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}
void update(int u, int l, int r, int x)
{
    tag[u] += x;
    sum[u] += (lld)x * (r - l + 1);
}
void pushdown(int u, int l, int r)
{
    if(tag[u]) {
        int mid = l + r >> 1;
        update(u << 1, l, mid, tag[u]);
        update(u << 1 | 1, mid + 1, r, tag[u]);
        tag[u] = 0;
    }
}
void modify(int u, int ul, int ur, int ml, int mr, int x)
{
    if(ml <= ul && mr >= ur) {
        update(u, ul, ur, x);
        return;
    }
    pushdown(u, ul, ur);
    int mid = ul + ur >> 1;
    if(ml <= mid)
        modify(u << 1, ul, mid, ml, mr, x);
    if(mid + 1 <= mr)
        modify(u << 1 | 1, mid + 1, ur, ml, mr, x);
    pushup(u);
}
lld query(int u, int ul, int ur, int ml, int mr)
{
    if(ml <= ul && mr >= ur) {
        return sum[u];
    }
    pushdown(u, ul, ur);
    int mid = ul + ur >> 1;
    lld s = 0;
    if(ml <= mid)  
        s += query(u << 1, ul, mid, ml, mr);
    if(mr >= mid + 1)
        s += query(u << 1 | 1, mid + 1, ur, ml, mr);
    return s;
}
int main()
{
    cin >> n >> m;
    build(1, 1, n);
    while(m--) {
        int ord, x, y, z;
        cin >> ord >> x >> y;
        if(ord == 1) {
            cin >> z;
            modify(1, 1, n, x, y, z);
        } else 
            cout << query(1, 1, n, x, y) << endl;
    }
return 0;
}

【模板】树状数组 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N = 5e5 + 5;
int n, m, t[N];
typedef long long lld;
int lowbit(int x)
{
    return x & -x;
}
void modify(int i, lld x)
{
    while(i <= n) {
        t[i] += x;
        i += lowbit(i);
    }
}
lld query(int i) 
{
    lld sum = 0;
    while(i) {
        sum += t[i];
        i -= lowbit(i);
    }
    return sum;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        modify(i, x);
    }
    for(int i = 1; i <= m; i++) {
        int ord, x, y;
        cin >> ord >> x >> y;
        if(ord == 1) {
            modify(x, y);
        } else {
            cout << query(y) - query(x - 1) << endl;
        }
    }
return 0;
}

【模板】线段树 2

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N = 1e5 + 1;
typedef long long lld;
int n, p, m;
lld sum[N << 2], plutag[N << 2], multag[N << 2];
void pushup(int u)
{
    sum[u] = sum[u << 1] + sum[u << 1 | 1];
    sum[u] %= p;
}
void build(int u, int l, int r) {
    multag[u] = 1;
    if(l == r) {
        cin >> sum[u];
        sum[u] %= p;
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}
void pushdown(int u, int m) 
{
    if(multag[u] == 1 && plutag[u] == 0)
        return;
    sum[u << 1] = (sum[u << 1] * multag[u] + (m - (m >> 1)) * plutag[u]) % p;
    sum[u << 1 | 1] = (sum[u << 1 | 1] * multag[u] + (m >> 1) * plutag[u]) % p;
    multag[u << 1] = (multag[u << 1] * multag[u]) % p;
    multag[u << 1 | 1] = (multag[u << 1 | 1] * multag[u]) % p;
    plutag[u << 1] = (plutag[u << 1] * multag[u] + plutag[u]) % p;
    plutag[u << 1 | 1] = (plutag[u << 1 | 1] * multag[u] + plutag[u]) % p;
    multag[u] = 1;
    plutag[u] = 0;
}
void pludate(int u, int l, int r, lld x)
{
    plutag[u] = (plutag[u] + x) % p;
    sum[u] = (sum[u] + x * (r - l + 1)) % p;
}
void muldate(int u, int l, int r, lld x)
{
    sum[u] = (sum[u] * x) % p;
    multag[u] = (multag[u] * x) % p;
    plutag[u] = (plutag[u] * x) % p;
}
void plu(int u, int ul, int ur, int ml ,int mr, int x) 
{
    if(ml <= ul && mr >= ur) {
        pludate(u, ul, ur, x);
        return;
    }
    pushdown(u, ur - ul + 1);
    int mid = ul + ur >> 1;
    if(ml <= mid) 
        plu(u << 1, ul, mid, ml, mr, x);
    if(mid + 1 <= mr) 
        plu(u << 1 | 1, mid + 1, ur, ml, mr, x);
    pushup(u);
}
void mul(int u, int ul, int ur, int ml, int mr, int x)
{
    if(ml <= ul && mr >= ur) {
        muldate(u, ul, ur, x);
        return;
    }
    pushdown(u, ur - ul + 1);
    int mid = ul + ur >> 1;
    if(ml <= mid)
        mul(u << 1, ul, mid, ml, mr, x);
    if(mid + 1 <= mr)
        mul(u << 1 | 1, mid + 1, ur, ml, mr, x);
    pushup(u);
}
lld query(int u, int ul, int ur, int ml, int mr)
{
    if(ml <= ul && mr >= ur) {
        return sum[u];
    }
    pushdown(u, ur - ul + 1);
    int mid = ul + ur >> 1;
    lld s = 0;
    if(ml <= mid) {
        s += query(u << 1, ul, mid, ml, mr);
        s %= p;
    }   
    if(mr >= mid + 1) {
        s += query(u << 1 | 1, mid + 1, ur, ml, mr);
        s %= p;
    }
    return s;
}
int main()
{
    cin >> n >> m >> p;
    build(1, 1, n);
    while(m--) {
        int ord, a, b;
        lld c;
        cin >> ord >> a >> b;
        if(ord == 1) {
            cin >> c;
            mul(1, 1, n, a, b, c);
        } else if(ord == 2) {
            cin >> c;
            plu(1, 1, n, a, b, c);
        } else {
            cout << (lld) query(1, 1, n, a, b) << endl;
        }
    }
return 0;
}

【模板】树状数组 2

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long lld;
const int N = 5e5 + 9;
int n, m;
lld a[N], d[N], id[N];
int lowbit(int x)
{
    return x & (-x);
}
void modify(lld *t, int i, lld x)
{
    while(i <= n) {
        t[i] += x;
        i += lowbit(i);
    }
}
lld query(lld *t, int i)
{
    lld sum = 0;
    while(i) {
        sum += t[i];
        i -= lowbit(i);
    }
    return sum;
}
lld q(int r)
{
    return (lld)query(d, r) * (r + 1) - query(id, r);
}
int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n; i ++) {
        cin >> a[i];
        modify(d, i, a[i] - a[i - 1]);
        modify(id, i, i * (a[i] - a[i - 1]));
    }
    while(m--) {
        lld opt, x, y, z;
        cin >> opt >> x;
        if(opt == 1) {
            cin >> y >> z;
            modify(d, x, z);
            modify(id, x, x * z);
            modify(d, y + 1, -z);
            modify(id, y + 1, (y + 1) *(-z));
        } else {
            cout << (lld)q(x) - q(x - 1) << endl;
        }
    }
return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!