线段树模板集合

别问我为什么是指针
也别问我为什么用了switch()(因为好玩)

单点修改+区间查询

#include 
#include 
#include 
#include 
using namespace std;
//Mystery_Sky
//线段树模板(单点修改+区间求和)
#define M 500050
#define Mid (l+r)>>1
struct Tree{
    Tree *lc, *rc;
    int x;
}dizhi[M<<1], *root = &dizhi[0];
int t = 1;
int a[M];
int n, m, k, x, y;
void build(Tree *tree, int l, int r)
{
    if(l == r) {
        tree->x = a[l];
        return;
    }
    int mid = Mid;
    tree->lc = &dizhi[++t];
    tree->rc = &dizhi[++t];
    build(tree->lc, l, mid);
    build(tree->rc, mid+1, r);
    tree->x = tree->lc->x + tree->rc->x;
} 

void update(Tree *tree, int l, int r, int x, int d)
{
    if(l == r) {
        tree->x += d;
        return;
    }
    int mid = Mid;
    if(x <= mid) update(tree->lc, l, mid, x, d);
    else update(tree->rc, mid+1, r, x, d);
    tree->x = tree->lc->x + tree->rc->x;
}

int query(Tree *tree, int l, int r, int x, int y)
{
    if(x <= l && y >= r) {
        return tree->x;
    }
    int mid = Mid;
    int ans = 0;
    if(x <= mid) ans += query(tree->lc, l, mid, x, y);
    if(y > mid) ans += query(tree->rc, mid+1, r, x, y);
    return ans;
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(root, 1, n);
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &k, &x, &y);
        switch(k){
            case 1:{
                update(root, 1, n, x, y);
                break;
            }
            case 2:{
                printf("%d\n", query(root, 1, n, x, y));
                break;
            }
        }
    }
    return 0;
}

区间修改+单点查询

#include 
#include 
#include 
#include 
using namespace std;
//Mystery_Sky
//线段树模板(区间修改+单点查询)
#define M 5000050
#define ll long long
#define INF 0x3f3f3f3f
#define Mid (l+r)>>1
struct Tree{
    Tree *lc, *rc;
    int x, lazy;
}dizhi[M<<1], *root = &dizhi[0];
int n, m, t=1;
int a[M];
int x, y, d, k;

void build(Tree *tree, int l, int r)
{
    if(l == r) {
        tree->x = a[l];
        return;
    }
    int mid = Mid;
    tree->lc = &dizhi[++t];
    tree->rc = &dizhi[++t];
    build(tree->lc, l, mid);
    build(tree->rc, mid+1, r);
    tree->x = tree->lc->x + tree->rc->x;
} 

inline void pushdown(Tree *tree, int l, int r)
{
    if(!tree->lazy) return;
    int mid = Mid;
    tree->lc->x += tree->lazy * (mid - l + 1);
    tree->rc->x += tree->lazy * (r - mid);
    tree->lc->lazy += tree->lazy;
    tree->rc->lazy += tree->lazy;
    tree->lazy = 0;
}

void update(Tree *tree, int l, int r, int x, int y, int d)
{
    if(x <= l && y >= r) {
        tree->x += d * (r - l + 1);
        tree->lazy += d;
        return;
    }
    pushdown(tree, l, r);
    int mid = Mid;
    if(x <= mid) update(tree->lc, l, mid, x, y, d);
    if(y > mid) update(tree->rc, mid+1, r, x, y, d);
    tree->x = tree->lc->x + tree->rc->x;
}

int query(Tree *tree, int l, int r, int x)
{
    if(l == r) {
        return tree->x;
    }
    pushdown(tree, l, r);
    int mid = Mid;
    if(x <= mid) return query(tree->lc, l, mid, x);
    else return query(tree->rc, mid+1, r, x);
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(root, 1, n);
    for(int i = 1; i <= m; i++) {
        scanf("%d", &k);
        switch(k) {
            case 1:{
                scanf("%d%d%d", &x, &y, &d);
                update(root, 1, n, x, y, d);
                break;
            }
            case 2:{
                scanf("%d", &x);
                printf("%d\n", query(root, 1, n, x));
                break;
            }
        }
    }
    return 0;
}

区间修改+区间查询

#include 
#include 
#include 
#include 
using namespace std;
//Mystery_Sky
//线段树模板(区间修改+区间查询)
#define M 5000050
#define ll long long
#define INF 0x3f3f3f3f
#define Mid (l+r)>>1
struct Tree{
    Tree *lc, *rc;
    ll x, lazy;
}dizhi[M<<1], *root = &dizhi[0];
int n, m, t=1;
int a[M];
int x, y, d, k;

void build(Tree *tree, int l, int r)
{
    if(l == r) {
        tree->x = a[l];
        return;
    }
    int mid = Mid;
    tree->lc = &dizhi[++t];
    tree->rc = &dizhi[++t];
    build(tree->lc, l, mid);
    build(tree->rc, mid+1, r);
    tree->x = tree->lc->x + tree->rc->x;
} 

inline void pushdown(Tree *tree, int l, int r)
{
    if(!tree->lazy) return;
    int mid = Mid;
    tree->lc->x += tree->lazy * (mid - l + 1);
    tree->rc->x += tree->lazy * (r - mid);
    tree->lc->lazy += tree->lazy;
    tree->rc->lazy += tree->lazy;
    tree->lazy = 0;
}

void update(Tree *tree, int l, int r, int x, int y, int d)
{
    if(x <= l && y >= r) {
        tree->x += (ll) d * (r - l + 1);
        tree->lazy += d;
        return;
    }
    pushdown(tree, l, r);
    int mid = Mid;
    if(x <= mid) update(tree->lc, l, mid, x, y, d);
    if(y > mid) update(tree->rc, mid+1, r, x, y, d);
    tree->x = tree->lc->x + tree->rc->x;
}

ll query(Tree *tree, int l, int r, int x, int y)
{
    if(x <= l && y >= r) {
        return tree->x;
    }
    pushdown(tree, l, r);
    int mid = Mid;
    ll ans = 0;
    if(x <= mid) ans += query(tree->lc, l, mid, x, y);
    if(y > mid) ans += query(tree->rc, mid+1, r, x, y);
    return ans;
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(root, 1, n);
    for(int i = 1; i <= m; i++) {
        scanf("%d", &k);
        switch(k) {
            case 1:{
                scanf("%d%d%d", &x, &y, &d);
                update(root, 1, n, x, y, d);
                break;
            }
            case 2:{
                scanf("%d%d", &x, &y);
                printf("%lld\n", query(root, 1, n, x, y));
                break;
            }
        }
    }
    return 0;
}

区间乘+区间加+区间查询

留坑待补

转载于:https://www.cnblogs.com/Benjamin-cpp/p/10920137.html

你可能感兴趣的:(线段树模板集合)