题解 | #区间和#

区间和

https://ac.nowcoder.com/acm/problem/50452

区间和

结构体

#include <iostream>

using namespace std;

const int N = 1e6 + 10;
typedef long long LL;

struct Node
{
    int l, r;
    LL sum;
}tr[N * 4];//线段树一般要开4倍数组
int n, m, a[N];

//通过两个子节点来相应调整父节点
void pushup(int u)
{
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

//建树
void build(int u, int l, int r)
{
    if(l == r) tr[u] = {l, r, a[l]};
    else
    {
        tr[u] = {l, r};        
        int mid = l + r >> 1;//写成tr[u].l + tr[u].r >> 1;也是一样的
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

//单点修改
void modify(int u, int x, int v)
{
    //如果正好是那个要修改的叶子节点
    if(tr[u].l == x && tr[u].r == x) tr[u].sum += v;
    else
    {
        int mid = tr[u].l + tr[u].r >> 1;
        //由于是单点修改,所以要么在左边要么在右边
        if(x <= mid) modify(u << 1, x, v);
        else modify(u << 1 | 1, x, v);
        pushup(u);//修改完记得pushup
    }
}

//区间查询
LL query(int u, int l, int r)
{
    //待查询区间完全包裹当前节点所代表的区间
    if(l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
    else
    {
        LL sum = 0;
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) sum += query(u << 1, l, r);//左子树包含待查询区间 (这里写=也可以)
        if(r > mid) sum += query(u << 1 | 1, l, r);//右子树包含待查询区间
        return sum;
    }
}

int main()
{
    cin >> n >> m;    
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    build(1, 1, n);
    
	int t, x, y;
	while(m --)
	{
		scanf("%d%d%d", &t, &x, &y);
		if(t == 1) modify(1, x, y);
		else printf("%lld\n", query(1, x, y));
	}
    
    return 0;
}

数组

#include <bits/stdc++.h>

#define lson u << 1, l, mid
#define rson u << 1 | 1, mid + 1, r

using namespace std;

const int N = 1e6 + 10;
typedef long long LL;

LL tr[N * 4];
int n, m;

void pushup(int u)
{
	tr[u] = tr[u << 1] + tr[u << 1 | 1];
}

void build(int u, int l, int r)
{
	if(l == r) scanf("%lld", &tr[u]);
	else
	{
		int mid = l + r >> 1;
		build(lson), build(rson);
		pushup(u);
	}
}

void modify(int u, int l, int r, int x, int v)
{
	if(l == x && r == x) tr[u] += v;
	else
	{
		int mid = l + r >> 1;
		if(x <= mid) modify(lson, x, v);
		else modify(rson, x, v);
		pushup(u);
	}
}

LL query(int u, int l, int r, int x, int y)
{
	if(x <= l && r <= y) return tr[u];
	else
	{
		LL sum = 0;
		int mid = l + r >> 1;
		if(x <= mid) sum += query(lson, x, y);
		if(y > mid) sum += query(rson, x, y);
		return sum;
	}
}

int main()
{
	cin >> n >> m;
	build(1, 1, n);
	
	while(m --)
	{
		int t, x, y;
		scanf("%d%d%d", &t, &x, &y);
		if(t == 1) modify(1, 1, n, x, y);
		else printf("%lld\n", query(1, 1, n, x, y));
	}
	
	return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务