线段树全TLE

P3372 【模板】线段树 1

ChenErxiang @ 2023-08-01 19:16:23

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read()
{
    ll s=0,w=1;char ch=getchar();
    while(ch>'9'||ch<'0')if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    return s*w;
}
const ll maxn=2e5+10;
ll n,m;//序列长,询问/修改个数
ll S[maxn];//序列
ll X,L,R,V;

ll sum[4*maxn]={0},add[4*maxn]={0};
void build(ll k,ll l,ll r)//建树 
{
    if(l==r)
    {
        sum[k]=S[l];
        return ;
    }
    ll mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    sum[k]=sum[k<<1]+sum[k<<1|1];
}
void Add(ll k,ll l,ll r,ll v)
{
    add[k]+=v;
    sum[k]+=(r-l+1)*v;
    return ;
}
void pushdown(ll k,ll l,ll r)//标记下传 
{
    if(add[k]==0)return ;
    ll mid=l+r>>1;
    Add(k<<1,l,mid,add[k]);//下传到左子树 
    Add(k<<1|1,mid+1,r,add[k]);//下传到右子树
    add[k]=0;//标记清零 
}
void modify(ll k,ll l,ll r,ll a,ll b,ll v)//区间增加v
{
    if(l>=a&&r<=b)return Add(k,l,r,v);
    ll mid=l+r>>1;
    pushdown(k,l,r);//到每一个节点都要标记下传 
    if(a<=mid)modify(k<<1,l,mid,a,b,v);
    if(mid<b)modify(k<<1|1,mid+1,r,a,b,v);
    sum[k]=sum[k<<1]+sum[k<<1|1];//标记下传后更新正确的sum值 
}
ll query(ll k,ll l,ll r,ll a,ll b)
{
    if(l>=a&&r<=b)return sum[k];
    ll res=0;
    ll mid=l+r>>1;
    pushdown(k,l,r);
    if(a<=mid)res+=query(k<<1,l,mid,a,b);
    if(mid<b)res+=query(k<1|1,mid+1,r,a,b);
    return res;
}

int main()
{
    n=read(),m=read();
    for(ll i=1;i<=n;i++)S[i]=read();
    build(1,1,n);
    while(m--)
    {
        X=read();
        switch(X)
        {
            case 1: L=read(),R=read(),V=read();modify(1,1,n,L,R,V);break;
            case 2: L=read(),R=read();printf("%lld\n",query(1,1,n,L,R));break;
        }

    }
    return 0;
}

by 1zsczsczsc @ 2023-08-01 19:23:23

modify函数无返回值


by ChenErxiang @ 2023-08-01 20:34:36

@1zsczsczsc 这个应该没关系吧


|