线段树 P3374 单点修改 区间查询

Posted jason66661010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树 P3374 单点修改 区间查询相关的知识,希望对你有一定的参考价值。

题目

https://www.luogu.com.cn/problem/P3374

代码

树状数组版:

#include<iostream>
#include<cstdio>
using namespace std;
long long a[500001], c[500001];
int n, m;
int lowbit(int x)
{
    return x&(-x);
}
void update(int i, int k)
{
    while (i <= n)
    {
        c[i] += k;
        i += lowbit(i);
    }
}
long long getsum(int i)
{
    long long res = 0;
    while (i > 0)
    {
        res += c[i];
        i -= lowbit(i);
    }
    return res;
}
int main()
{
    int aa, bb, cc;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
        update(i, a[i]);
    }
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d%d", &aa, &bb, &cc);
        if (aa == 1)
            update(bb, cc);
        else
            printf("%lld
", getsum(cc) - getsum(bb - 1));
    }

}

线段树版:

#include<iostream>
#include<cstdio>
using namespace std;
int n, m;
long long a[500001], c[500001*4];
void build(int l, int r, int k)
{
    if (l == r)
        c[k] = a[l];
    else
    {
        int mid = (l + r) >> 1;
        build(l, mid, k << 1);
        build(mid + 1, r, k << 1 | 1);
        c[k] = c[k << 1] + c[k << 1 | 1];
    }
}
void update(int index, int v, int l, int r, int k)
{
    if (l == r)
        a[l]+=v,c[k] += v;
    else
    {
        int mid = (l + r) >> 1;
        if (mid >= index)
            update(index, v, l, mid, k << 1);
        else
            update(index, v, mid + 1, r, k << 1 | 1);
        c[k] = c[k << 1] + c[k << 1 | 1];
    }
}
long long query(int L, int R, int l, int r, int k)
{
    if (L <= l&&R >= r)
        return c[k];
    else
    {
        long long res = 0;
        int mid = (l + r) >> 1;
        if (L <= mid)
            res += query(L, R, l, mid, k << 1);
        if (R > mid)
            res += query(L, R, mid + 1, r, k << 1 | 1);
        return res;
    }
}
int main()
{
    int aa, bb, cc;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    build(1, n, 1);
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d%d", &aa, &bb, &cc);
        if (aa == 1)
            update(bb,cc,1,n, 1);
        else
            printf("%lld
", query(bb,cc,1,n,1));
    }

}

 

以上是关于线段树 P3374 单点修改 区间查询的主要内容,如果未能解决你的问题,请参考以下文章

线段树详解

模板线段树-单点修改,区间查询

线段树 建树 单点修改 点点/区间查询

线段树(单点修改+区间查询)&(区间修改+区间查询)

HDU 1166 - 敌兵布阵 - [单点修改区间查询zkw线段树]

线段树 区间修改,单点查询