线段树 - 单点更新/查询,区间更新/查询

 区间更新,区间求和:

#include 
using namespace std;
#define ll long long
#define lefs l, m, rt << 1
#define rigs m+1, r, rt << 1 | 1
#define lef rt << 1
#define rig rt << 1 | 1
#define mid (l + r) >> 1;
#define abb int l, int r, int rt
const int N = 1e5 + 7;
int n, m;
ll sum[N << 2], lazy[N << 2];
void pushup(int rt)
{
    sum[rt] = sum[lef] + sum[rig];
}
void pushdown(abb)
{
    if(lazy[rt])
    {
        lazy[lef] += lazy[rt];
        lazy[rig] += lazy[rt];
        int m = mid;
        sum[lef] += (m - l + 1) * lazy[rt];
        sum[rig] += (r - m) * lazy[rt];
        lazy[rt] = 0;
    }
}
void build(abb)
{
    if(l == r)
    {
        scanf("%lld",&sum[rt]);
        return;
    }
    int m = mid;
    build(lefs); build(rigs);
    pushup(rt);
}
void update(int L, int R, ll val, abb)
{
    if(l >= L && r <= R)
    {
        lazy[rt] += val;
        sum[rt] += (r - l + 1) * val;
        return ;
    }
    pushdown(l, r, rt);
    int m = mid;
    if(m >= L) update(L, R, val, lefs);
    if(m < R) update(L, R, val, rigs);
    pushup(rt);
}
ll query(int L, int R, abb)
{
    if(l >= L && r <= R)
        return sum[rt];
    pushdown(l, r, rt);
    int m = mid; ll ans = 0;
    if(m >= L) ans += query(L, R, lefs);
    if(m < R) ans += query(L, R, rigs);
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    build(1, n, 1);
    int op, x, y; ll val;
    while(m--)
    {
        scanf("%d",&op);
        if(op == 1)
        {
            scanf("%d%d%lld",&x, &y, &val);
            update(x, y, val, 1, n, 1);
        }
        else
        {
            scanf("%d%d",&x, &y);
            cout << query(x, y, 1, n, 1) << endl;
        }
    }
}

单点更新/查询,区间更新/查询 :

#include 
#include 
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid (l+r)>>1
#define abb int l,int r,int rt
const int N = 1e5 + 7;
ll lazy[N<<2];
ll sum[N<<2];
inline void pushup(int rt)//更新父亲节点
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
inline void pushdown(abb) //标记下传
{
    if(lazy[rt])
    {
        lazy[rt<<1] += lazy[rt];
        lazy[rt<<1|1] += lazy[rt];
        int m = mid;
        sum[rt<<1] += (m-l+1) * lazy[rt];
        sum[rt<<1|1] += (r-m) * lazy[rt];
        lazy[rt] = 0;
    }
}

inline void build(abb)
{
    lazy[rt] = 0;
    if(l == r)
    {
        scanf("%lld", &sum[rt]);
        return ;
    }
    int m = mid;
    build(lson);
    build(rson);
    pushup(rt);
}
inline void update(int L, int R, int c, abb)
{
    if(L <= l && R >= r)
    {
        lazy[rt] += c;
        sum[rt] += (r-l+1) * c;
        return ;
    }
    pushdown(l, r, rt);
    int m = mid;
    if(L <= m) update(L, R, c, lson);
    if(R > m)  update(L, R, c, rson);
    pushup(rt);
}
inline ll query(int L, int R, abb)
{
    if(L <= l && R >= r)
        return sum[rt];
    pushdown(l, r, rt);
    int m = mid;
    ll ret = 0;
    if(L <= m)   ret += query(L, R, lson);
    if(R > m)    ret += query(L, R, rson);
    return ret;
}
inline void update_point(int p, int c, abb)
{
    if(l == r)
    {
        sum[rt] += c;
        return ;
    }
    pushdown(l, r, rt);
    int m = mid;
    if(p <= m) update_point(p, c, lson);
    else update_point(p, c, rson);
    pushup(rt);
}
inline ll query_point(int p, abb)
{
    if(l == r)
        return sum[rt];
    pushdown(l, r, rt);
    int m = mid;
    if(p <= m)  query_point(p, lson);
    else  query_point(p, rson);
}
int main()
{
    int m,n;
    scanf("%d%d",&n, &m);
    build(1, n, 1);
    while(m--)
    {
        int a, b, c, p, op;
        scanf("%d",&op);
        if(op == 1) //单点更新
        {
            scanf("%d%d", &p, &c);
            update_point(p, c, 1, n, 1);
        }
        if(op == 2) //单点查询
        {
            scanf("%d", &p);
            printf("%lld\n",query_point(p, 1, n, 1));
        }
        if(op == 3) //区间更改
        {
            scanf("%d%d%d", &a, &b, &c);
            update(a,b,c,1,n,1);
        }
        if(op == 4) //区间查询
        {
            scanf("%d%d", &a, &b);
            printf("%lld\n",query(a, b, 1, n, 1));
        }
    }
    return 0;
}

 

你可能感兴趣的:(线段树 - 单点更新/查询,区间更新/查询)