WA 0 求调,代码shishan望谅解

P3372 【模板】线段树 1

Maple_Mourn @ 2024-11-20 19:22:29

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int n,m,num;
ll cnt;
struct nod{
    int l,r;
    ll w,f;
}tr[500005*4];
void build(int k,int x,int y){
    tr[k].l=x,tr[k].r=y;
    if(tr[k].l==tr[k].r){scanf("%lld",&tr[k].w);return ;}
    int mid=(x+y)>>1;
    build(k*2,x,mid);
    build(k*2+1,mid+1,y);
    tr[k].w=tr[k*2].w+tr[k*2+1].w;
}
void down(int k){
    tr[k*2].w+=tr[k].f*(tr[k*2].r-tr[k*2].l+1);
    tr[k*2+1].w+=tr[k].f*(tr[k*2+1].r-tr[k*2+1].l+1);
    tr[k*2].f+=tr[k].f;
    tr[k*2+1].f+=tr[k].f;
    tr[k].f=0;
}
void add(int k,int x,int y,ll num){
    if(x<=tr[k].l&&y>=tr[k].r){
        tr[k].f+=num;
        tr[k].w+=num*(tr[k].r-tr[k].l+1);
        return ;
    }
    if(tr[k].f) down(k);
    if(x<=tr[k].l) add(k*2,x,y,num);
    if(y>tr[k].r) add(k*2+1,x,y,num);
    tr[k].w=tr[k*2].w+tr[k*2+1].w;
}
void ask(int k,int x,int y){
    if(x<=tr[k].l&&y>=tr[k].r){
        cnt+=tr[k].w;
        return ;
    }
    if(tr[k].f) down(k);
    if(x<=tr[k].l) ask(k*2,x,y);
    if(y>tr[k].r) ask(k*2+1,x,y);
}
int main(){
    cin>>n>>m;
    build(1,1,n);
    while(m--){
        int id,x,y;
        long long k;
        scanf("%d%d%d",&id,&x,&y);
        if(id==1){
            scanf("%lld",&num);
            add(1,x,y,num);
        }else{
            cnt=0;
            ask(1,x,y);
            printf("%lld\n",cnt);
        }
    }
    return 0;
}

by DLDZD @ 2024-11-20 19:30:53

    if(x<=tr[k].l) ask(k*2,x,y);
    if(y>tr[k].r) ask(k*2+1,x,y);

这里有问题@Maple_Mourn


by M1KuM3yusQAQ @ 2024-11-20 19:31:38

check here:

if(x<=tr[k].l) add(k*2,x,y,num);
if(y>tr[k].r) add(k*2+1,x,y,num);

by Maple_Mourn @ 2024-11-20 19:32:16

@DLDZD 感谢感谢%%%


by DLDZD @ 2024-11-20 19:32:27

你要求mid,这样才可以枚举左右儿子。

int mid=(tr[k].l+tr[k].r)/2;
if(x<=mid) ask(k*2,x,y);
if(y>mid) ask(k*2+1,x,y);

你的add也一样


by Maple_Mourn @ 2024-11-20 19:32:38

@M1KuM3yusQAQ 谢谢


|