线段树全TLE
查看原帖
线段树全TLE
386385
ChenErxiang楼主2023/8/1 19:16
#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;
}
2023/8/1 19:16
加载中...