10pts WA求条

P3372 【模板】线段树 1

Unblocked_user @ 2024-12-14 11:10:04

已经用了各种方法了,从昨天晚上弄到现在都没整出来。

#include<bits/stdc++.h>
#define lid id<<1   //lid表示左儿子的编号 
#define rid id<<1|1     //rid表示右儿子二点编号 
#define int long long
using namespace std;
const int N=4e5+5,M=1e5+5;  //线段树开四倍内存 
int n,m,a[M];
int op,x,y,k;
struct qweqweqwe{   //线段树 
    int l,r;    //区间 
    int sum;    //区间累加和 
    int lazy;   //lazy标记 
}t[N];
void mt(int l,int r,int id){    //建树,确认没问题 
    t[id].l=l,t[id].r=r;
    if(l==r){
        t[id].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    mt(l,mid,lid);
    mt(mid+1,r,rid);
    t[id].sum=t[lid].sum+t[rid].sum;
}
int ask(int l,int r,int id){    //区间查询。l表示当前区间的左边,r表示当前区间的右边,id表示当前区间的编号 
    if(x<=l&&r<=y){     //如果当前区间被查询区间全包含 
        return t[id].sum;   //直接放回当前区间累加值
    }
    int mid=(l+r)>>1,res=0;     //中间点 
    if(t[id].lazy){     //懒标记下放 
        t[lid].lazy+=t[id].lazy;
        t[rid].lazy+=t[id].lazy;
        t[lid].sum+=(t[lid].r-t[lid].l+1)*t[lid].lazy;
        t[rid].sum+=(t[rid].r-t[rid].l+1)*t[rid].lazy;
        t[id].lazy=0;
    }
    if(x<=mid)res+=ask(l,mid,lid);      //向左查询 
    if(y>mid)res+=ask(mid+1,r,rid);     //向右查询 
    return res;     //返回查询到的结果 
}
void change(int l,int r,int id){    //区间修改,参数含义与 区间查询 一致 
    if(x<=l&&r<=y){     //如果当前区间被查询区间真包含 
        t[id].lazy+=k;  //添加懒标记 
        t[id].sum+=(r-l+1)*k;   //更新当前区间累加值 
        return;
    }
    int mid=(l+r)>>1;
    if(t[id].lazy){     //懒标记下放 
        t[lid].lazy+=t[id].lazy;
        t[rid].lazy+=t[id].lazy;
        t[lid].sum+=(t[lid].r-t[lid].l+1)*t[lid].lazy;
        t[rid].sum+=(t[rid].r-t[rid].l+1)*t[rid].lazy;
        t[id].lazy=0;
    }
    if(x<=mid)change(l,mid,lid);    //向左修改 
    if(y>mid)change(mid+1,r,rid);   //向右修改 
    t[id].sum=t[lid].sum+t[rid].sum;    //更新当前区间累加值 
}
signed main(){      //主函数,确定没问题 
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    mt(1,n,1);
    while(m--){
        cin>>op;
        if(op==1){
            cin>>x>>y>>k;
            change(1,n,1);
        }
        else{
            cin>>x>>y;
            cout<<ask(1,n,1)<<endl;
        }
    }
    return 0;
}

by JoyLosingK @ 2024-12-14 11:36:00

@Unblocked_user

#include<bits/stdc++.h>
#define lid id<<1   //lid表示左儿子的编号 
#define rid id<<1|1     //rid表示右儿子二点编号 
#define int long long
using namespace std;
const int N=4e5+5,M=1e5+5;  //线段树开四倍内存 
int n,m,a[M];
int op,x,y,k;
struct qweqweqwe{   //线段树 
    int l,r;    //区间 
    int sum;    //区间累加和 
    int lazy;   //lazy标记 
}t[N];
void mt(int l,int r,int id){    //建树,确认没问题 
    t[id].l=l,t[id].r=r;
    if(l==r){
        t[id].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    mt(l,mid,lid);
    mt(mid+1,r,rid);
    t[id].sum=t[lid].sum+t[rid].sum;
}
int ask(int l,int r,int id){    //区间查询。l表示当前区间的左边,r表示当前区间的右边,id表示当前区间的编号 
    if(x<=l&&r<=y){     //如果当前区间被查询区间全包含 
        return t[id].sum;   //直接放回当前区间累加值
    }
    int mid=(l+r)>>1,res=0;     //中间点 
    if(t[id].lazy){     //懒标记下放 
        t[lid].lazy+=t[id].lazy;
        t[rid].lazy+=t[id].lazy;
        t[lid].sum+=(t[lid].r-t[lid].l+1)*t[id].lazy;
        t[rid].sum+=(t[rid].r-t[rid].l+1)*t[id].lazy;
        t[id].lazy=0;
    }
    if(x<=mid)res+=ask(l,mid,lid);      //向左查询 
    if(y>mid)res+=ask(mid+1,r,rid);     //向右查询 
    return res;     //返回查询到的结果 
}
void change(int l,int r,int id){    //区间修改,参数含义与 区间查询 一致 
    if(x<=l&&r<=y){     //如果当前区间被查询区间真包含 
        t[id].lazy+=k;  //添加懒标记 
        t[id].sum+=(r-l+1)*k;   //更新当前区间累加值 
        return;
    }
    int mid=(l+r)>>1;
    if(t[id].lazy){     //懒标记下放 
        t[lid].lazy+=t[id].lazy;
        t[rid].lazy+=t[id].lazy;
        t[lid].sum+=(t[lid].r-t[lid].l+1)*t[id].lazy;
        t[rid].sum+=(t[rid].r-t[rid].l+1)*t[id].lazy;
        t[id].lazy=0;
    }
    if(x<=mid)change(l,mid,lid);    //向左修改 
    if(y>mid)change(mid+1,r,rid);   //向右修改 
    t[id].sum=t[lid].sum+t[rid].sum;    //更新当前区间累加值 
}
signed main(){      //主函数,确定没问题 
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    mt(1,n,1);
    while(m--){
        cin>>op;
        if(op==1){
            cin>>x>>y>>k;
            change(1,n,1);
        }
        else{
            cin>>x>>y;
            cout<<ask(1,n,1)<<endl;
        }
    }
    return 0;
}

lazy标记下传写错了


by Unblocked_user @ 2024-12-19 15:23:21

@JoyLosingK

谢dalao,已关


|