szbszb @ 2019-02-16 20:03:31
#include <bits/stdc++.h>
using namespace std;
long long n,m,i,q,x,y,a,j,l[5000001],r[5000001],z[5000001],t[500001],w[5000001],c[5000001],k,x1[100001];
bool b[5000001];
void xiafang(long long u)
{
z[u*2]+=c[u]*(r[u*2]-l[u*2]+1);
c[u*2]+=c[u];
z[u*2+1]+=c[u]*(r[u*2+1]-l[u*2+1]+1);
c[u*2+1]+=c[u];
c[u]=0;
}
void build(long long u,long long l1,long long r1)
{
l[u]=l1;
r[u]=r1;
if (l1==r1)
{
z[u]=x1[l1];
if (z[u]>=0)
b[u]=true;
return;
}
build(u*2,l1,(l1+r1)/2);
build(u*2+1,(l1+r1)/2+1,r1);
z[u]=(z[u*2]>0?z[u*2]:0)+(z[u*2+1]>0?z[u*2+1]:0);
b[u]=b[u*2]&b[u*2+1];
}
void jia(long long u,long long l1,long long r1,long long k)
{
if ((l[u]>r1)||(r[u]<l1)) return;
if ((l[u]>=l1)&&(r[u]<=r1))
{
if (b[u])
{
z[u]+=k*(r[u]-l[u]+1);
c[u]+=k;
}
else
{
if (l[u]==r[u])
{
z[u]=z[u]+k;
if (z[u]>=0) b[u]=true;
}
else
{
jia(u*2,l1,r1,k);
jia(u*2+1,l1,r1,k);
z[u]=(z[u*2]>0?z[u*2]:0)+(z[u*2+1]>0?z[u*2+1]:0);
b[u]=b[u*2]&b[u*2+1];
}
}
return;
}
xiafang(u);
jia(u*2,l1,r1,k);
jia(u*2+1,l1,r1,k);
z[u]=(z[u*2]>0?z[u*2]:0)+(z[u*2+1]>0?z[u*2+1]:0);
b[u]=b[u*2]&b[u*2+1];
}
long long qui(long long u,long long l1,long long r1)
{
if ((l1>r[u])||(r1<l[u])) return 0;
else if ((l1<=l[u])&&(r1>=r[u])) return (z[u]>0?z[u]:0);
else
{
if (c[u]>0) xiafang(u);
return (qui(u*2,l1,r1)+qui(u*2+1,l1,r1));
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for (i=1; i<=n; i++)
scanf("%lld",&x1[i]);
build(1,1,n);
//for (i=1; i<=10; i++) cout<<he[i];
for (i=1; i<=m; i++)
{
scanf("%lld%lld%lld",&q,&x,&y);
if (q==1)
{
scanf("%lld",&k);
jia(1,x,y,k);
}
else printf("%lld\n",qui(1,x,y));
//for (j=1; j<=9; j++) cout<<z[j]<<' ';
//cout<<endl;
//for (j=1; j<=9; j++) cout<<w[j]<<' ';
//cout<<endl;
}
return 0;
}
线段树咋T掉了呀?
by 142857cs @ 2019-02-16 20:04:57
区间加,区间最大子段和,不能用线段树啊
by 142857cs @ 2019-02-16 20:06:37
你的线段树直接递归到了叶子,复杂度不对啊
by szbszb @ 2019-02-17 11:40:37
@142857cs 谢谢(另外,布尔数组是让那些区间内都是大于零的不用递归到叶子)