样例没过的线段树求调

P3372 【模板】线段树 1

1234567890hh @ 2023-08-24 11:01:02

using namespace std;
typedef long long ll;
struct node{
    int l,r,lazy=0;
    ll ans;
}tree[500001];//线段树
long dat[100000];//存放原数据
int n,m;
bool inRange(int l,int r,int L,int R);
void pushdown(int i);
void build(int l,int r,int p){
    tree[p].l=l;
    tree[p].r=r;
    if(l==r){
        tree[p].ans=dat[l];
        return;
    }
    ll mid=(l+r)>>1;//右移1位等价于除以2
    build(l,mid,(p<<1));//左移一位等价于乘以二
    build(mid+1,r,(p<<1)|1);//左移后末位必是0,与1按位或相当于加1
    tree[p].ans=tree[p<<1].ans+tree[(p<<1)|1].ans;
}
void change(int i,int l,int r,int k){
    if(tree[i].r<=r&&tree[i].l>=l){
        tree[i].ans+=k*(tree[i].r-tree[i].l+1);
        tree[i].lazy+=k;
        return;
    }else{
        if(tree[i].lazy!=0){
            pushdown(i);
        }
        if(tree[i*2].r>=l){
            change(i*2,l,r,k);
        }
        if(tree[i*2+1].l<=r){
            change(i*2+1,l,r,k);
        }
        tree[i].ans=tree[i*2].ans+tree[i*2+1].ans;
    }
}
void pushdown(int i){
    tree[i*2].lazy+=tree[i].lazy;
    tree[i*2+1].lazy+=tree[i].lazy;
    ll mid=(tree[i].r+tree[i].l)>>1;
    tree[i*2].ans+=tree[i].lazy*(mid-tree[i].l+1);
    tree[i*2+1].ans+=tree[i].lazy*(tree[i].r-mid);
    tree[i].lazy=0;
}
ll ask(int i,int l,int r){
    if(inRange(tree[i].l,tree[i].r,l,r)){
        return (tree[i].ans);
    }else{
        ll t=0;
        if(tree[i*2].r>=l){
            t+=ask(i*2,l,r);
        }
        if(tree[i*2+1].l<=r){
            t+=ask(i*2+1,l,r);
        }
        return t;
    }
}
bool inRange(int l,int r,int L,int R){
    if(L<=l&&R>=r)return true;
    else
        return false;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>dat[i];
    build(1,n,1);//l,r,p
    int p,x,y,k;
    for(int i=1;i<=m;i++){
        cin>>p;
        if(p==1){//区间加
            cin>>x>>y>>k;
            change(1,x,y,k);//从根节点1开始搜,把区间[x,y]加上k
        }else{//区间求和
            cin>>x>>y;
            cout<<ask(1,x,y)<<endl;
        }
    }
    return 0;
}

样例输入 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 输出: 11 8 16 似乎是1-5区间加一的时候没加上 大佬求调


by LZMkingNB @ 2023-08-24 11:03:58

@1234567890hh 虫大,放代码不放全TT


by _zhy @ 2023-08-24 11:05:53

@1234567890hh ask 函数也要 push_down


by _zhy @ 2023-08-24 11:06:19

push_down 了就过了


by 1234567890hh @ 2023-08-24 11:07:39

ask()里面忘记下传懒标记


by 1234567890hh @ 2023-08-24 11:08:00

@_zhy 确实


by 1234567890hh @ 2023-08-24 11:08:59

@_zhy https://www.luogu.com.cn/record/122512768 70pts QAQ


by _zhy @ 2023-08-24 11:12:19

@1234567890hh 我用你的代码过了

代码


by _zhy @ 2023-08-24 11:15:37

@1234567890hh 开O2就A了


by _zhy @ 2023-08-24 11:18:39

@1234567890hh dat 数组小了


by 1234567890hh @ 2023-08-24 11:28:49

OK谢谢 此贴结


|