自学的不知道是不是线段树的东西(可还行)
有dalao愿意看看吗?(似乎比正常的线段树快??)
是不是因为数据水呀(会不会被更强力数据卡?)
这里是时间情况
#include<bits/stdc++.h>
using namespace std;
long long a[1000500],tr[1000500],ans[1000500],b[1000500],lazy[1000500];
long long mid,n,m,ji=0,sum=0;
void build(long long k,long long l,long long r)
{
if(l==r)
{
tr[k]=a[l];
return ;
}
long long mid=(r-l)/2+l;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
tr[k]=tr[k*2+1]+tr[k*2];//»ù±¾²Ù×÷
}//建树
void gai(long long k,long long l,long long r,long long cha1,long long cha2,long long jia)//cha1为查找区间左端点,cha2为右端点,l为左区间,r为右区间,jia为操作
{
if(l==cha1&&r==cha2)
{
lazy[k]+=jia;
return ;
}
tr[k]+=(cha2-cha1+1)*jia;
if(l<=cha1&&r>=cha2)
{
long long mid=(r-l)/2+l;
if(mid>=cha2)
{
gai(k*2,l,mid,cha1,cha2,jia);
}
if(mid+1<=cha1)
{
gai(k*2+1,mid+1,r,cha1,cha2,jia);
}
if(mid<cha2&&cha1<mid+1)
{
gai(k*2,l,mid,cha1,mid,jia);
gai(k*2+1,mid+1,r,mid+1,cha2,jia);
}
}
} //-------------------------------------------------------------------
void yong(long long k,long long l,long long r,long long cha1,long long cha2)
//cha1为查找区间左端点,cha2为右端点,l为左区间,r为右区间
{
if(l==cha1&&r==cha2)
{
sum=sum+tr[k]+(r-l+1)*lazy[k];
return ;
}
if(l<=cha1&&r>=cha2)
{
if(lazy[k]!=0)
{
lazy[k*2]+=lazy[k];
lazy[k*2+1]+=lazy[k];
tr[k]+=(r-l+1)*lazy[k];
lazy[k]=0;
}
long long mid=(r-l)/2+l;
if(mid>=cha2) yong(k*2,l,mid,cha1,cha2);
if(mid+1<=cha1) yong(k*2+1,mid+1,r,cha1,cha2);
if(mid<cha2&&cha1<mid+1)
{
yong(k*2,l,mid,cha1,mid);
yong(k*2+1,mid+1,r,mid+1,cha2);
}
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
build(1,1,n);
long long pan,l1,l2,c;
for(long long i=1;i<=m;i++)
{
scanf("%lld",&pan);
if(pan==1)
{
scanf("%lld%lld%lld",&l1,&l2,&c);
gai(1,1,n,l1,l2,c);//修改
}
if(pan==2)
{
ji++;
scanf("%lld%lld",&l1,&l2);
sum=0;
yong(1,1,n,l1,l2);//查询
ans[ji]=sum;
sum=0;
}
}
for(long long i=1;i<=ji;i++)
{
printf("%lld\n",ans[i]);
}
return 0;
}