全wa求助,不知道哪里细节错了

P3372 【模板】线段树 1

CurryNo_1 @ 2023-03-26 21:18:02

#include<iostream>
#include<algorithm>
#define lc 2*k
#define rc 2*k+1
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll n,m,a[N],x,y,z,q,sum;
struct node{
    int l;
    int r;
    ll mx;
} tree[4*N];
void build(ll k,ll l,ll r)
{
    tree[k].l=l;
    tree[k].r=r;
    if(l==r)  
    {
        tree[k].mx=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    tree[k].mx=tree[lc].mx+tree[rc].mx;//储存区间和 
}
void add(ll k,ll l,ll r,ll v)
{
    if(tree[k].l==tree[k].r)
    {
        tree[k].mx+=v;
        return;
    }
    ll mid=(r+l)>>1;
    if(l>mid)  add(rc,l,r,v);//区间全部位于右子树
    else if(r<=mid)  add(lc,l,r,v);//区间全部位于左子树 
    else
    {
        add(lc,l,mid,v);
        add(rc,mid+1,r,v);
    } 
    tree[k].mx=tree[lc].mx+tree[rc].mx;//从底层回溯是改变父节点的值 
    return;
}
ll query(ll k,ll l,ll r)
{
    ll res=0;
    if(tree[k].l>=l && tree[k].r<=r)
    {
        return  tree[k].mx;
    }
    ll mid=(tree[k].l+tree[k].r)>>1;
    if(l>mid)  res+=query(rc,l,r);
    else if(r<=mid)  res+=query(lc,l,r);
    else
    {
        res+=query(lc,l,mid);
        res+=query(rc,mid+1,r);
    }
    return res;
}
int main()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++)  cin >> a[i];
    build(1,1,n);//建树 
    for(int i=1;i<=m;i++)
    {
        cin >> x;
        if(x==1)//区间加操作 
        {
            cin >> y >> z >> q;
            add(1,y,z,q);
        }
        else if(x==2)//查询操作 
        {
            cin >> y >> z;
            cout << query(1,y,z) << endl;
        }
    }
    return 0;
} 

by zdl777 @ 2023-03-26 21:42:13

不只是细节问题啊。 qaq

首先线段树区间修改需要懒标记。

细节问题的话 update 里面

ll mid=(r+l)>>1;

改成

ll mid=(tree[k].l+tree[k].r)>>1;

by FstAutoMaton @ 2023-03-26 21:42:54

@CurryNo_1 你需要push_down函数


by CurryNo_1 @ 2023-03-26 21:49:46

@zdl777 一定需要懒标记吗


by CurryNo_1 @ 2023-03-26 21:50:40

@zdl777 一定需要懒标记吗


by CurryNo_1 @ 2023-03-26 21:54:06

@zdl777 ll=(l+r)>>1改完了70pts,最后三个点tle了,应该是没有懒标记


by CurryNo_1 @ 2023-03-26 21:54:20

@caoshurui ll=(l+r)>>1改完了70pts,最后三个点tle了,应该是没有懒标记


by zdl777 @ 2023-03-26 22:05:15

@CurryNo_1 没有懒标记复杂度有问题,我每次给你一个 [1, n] 的修改,没有懒标记每次都要改整棵线段树,复杂度是 O(mn\log n) 的。


by CurryNo_1 @ 2023-03-26 23:09:14

@zdl777 行,谢谢解答


|