萌新刚学OI,线段树求调

P3372 【模板】线段树 1

syr1125 @ 2022-12-22 14:01:44

rt

#include <bits/stdc++.h>
using namespace std;

#define lson (id << 1)
#define rson (id << 1 | 1) 
#define IAKIOI puts("QwQ")

struct tree
{
    int l, r;
    long long sum, lazy;
}t[400005];

int a[100005], n, T;

//build segment tree
void push_up(int id)
{
    t[id].sum = t[lson].sum + t[rson].sum;
} 

void build(int id, int l, int r)
{
    t[id].l = l, t[id].r = r;
    if (l == r)
    {
        t[id].sum = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(lson, l, mid);
    build(rson, mid + 1, r);
    push_up(id);
}

//add 
void push_down(int id, int l, int r)
{
    if (t[id].lazy)
    {
        int mid = (l + r) >> 1;
        t[lson].lazy += t[id].lazy;
        t[rson].lazy += t[id].lazy;

        t[lson].sum += t[id].lazy * (mid - l + 1);
        t[rson].sum += t[id].lazy * (r - mid);
        t[id].lazy = 0;
    }
}

void change(int id, int l, int r, long long x)
{
    int L = t[id].l, R = t[id].r;
    if (l <= L && R <= r)
    {
        t[id].sum += (R - L + 1) * x;
        t[id].lazy += x;
        return;
    }
    int mid = (L + R) >> 1;
    push_down(id, L, R);
    if (l <= mid)     
    {
        change(lson, l, r, x);
    }
    if (r > mid)
    {
        change(rson, l, r, x);
    }
    push_up(id);
}

//query
long long query(int id, int l, int r)
{
    int L = t[id].l, R = t[id].r;
    if (l <= L && R <= r)
    {
        return t[id].sum;
    }
    push_down(id, l, r);
    int mid = (L + R) >> 1;
    long long ans = 0;
    if (l <= mid)     
    {
        ans += query(lson, l, r);
    }
    if (r > mid)
    {
        ans += query(rson, l, r);
    }
    return ans;
}

int main()
{
    scanf("%d%d", &n, &T);
    for (int i = 1; i <= n; i ++)
    {
        scanf("%d", &a[i]);
    }

    build(1, 1, n);

    while (T --)
    {
        int op;
        scanf("%d", &op);
        if (op == 1)
        {
            int x, y, k;
            scanf("%d%d%d", &x, &y, &k);
            change(1, x, y, k);
        }
        else if (op == 2)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            printf("%lld\n", query(1, x, y));
        }
    }
    return 0;
} 

线段树自学的

可能出一些很离谱的错误 ( 但是我查不出来 )


by char_cha_ch @ 2022-12-22 14:22:42

@syr1125 你知道吗,节点表示的区间长度和函数表示的区间长度是不一样的。pushdown 的时候你会出错,注意付给 pushdown 的参数。


by SHOJYS @ 2022-12-22 14:25:39

@syr1125 你push_down函数有问题 改成:

t[lson].sum += t[id].lazy * (t[lson].r - t[lson].l + 1);
t[rson].sum += t[id].lazy * (t[rson].r - t[rson].l + 1);

by SHOJYS @ 2022-12-22 14:26:28

我不知道我会不会改错,因为我写线段树很少这么写。


by xixisuper @ 2022-12-22 15:03:59

@syr1125 如果没有看错的话,你的 query 函数里面 push_down 的参数给错了

你的是

push_down(id, l, r);

应该是要改成

push_down(id, L, R);

by syr1125 @ 2022-12-22 18:20:13

谢谢大佬们


|