蒟蒻求助
分块思想做线段树(我是伞兵
但我还是想知道错在哪里
蟹蟹了!
#include<algorithm>
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;
inline int read(){
char c=getchar();int f=1,x=0;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-48;c=getchar();}
return x*f;
}
ll n,m,sq,pd,x,y,k;
ll a[N],st[N],ed[N],bel[N],siz[N],sum[N],mark[N];
void init(int n){
sq=sqrt(n);
for(int i=1;i<=sq;++i){
st[i]=sq*(i-1)+1;
ed[i]=sq*i;
}
ed[sq]=n;
for(int i=1;i<=sq;++i)
for(int j=st[i];j<=ed[i];++j)
bel[j]=i;//判断从属关系
for(int i=1;i<=sq;++i)
siz[i]=ed[i]-st[i]+1;
}
void change(int x,int y,int k){
if(bel[x]==bel[y]){
for(int i=x;i<=y;++i){
a[i]+=k;
sum[bel[i]]+=k;
}
}
else{
for(int i=x;i<=ed[bel[x]];++i){
a[i]+=k;
sum[bel[x]]+=k;
}
for(int i=st[bel[y]];i<=y;++i){
a[i]+=k;
sum[bel[x]]+=k;
}
for(int i=bel[x]+1;i<bel[y];++i)mark[i]+=k;
}
}
ll query(int x,int y){
ll ans=0;
if(bel[x]==bel[y]){
for(int i=x;i<=y;++i){
ans+=a[i]+mark[bel[i]];
}
}
else{
for(int i=x;i<=ed[bel[x]];++i)
ans+=a[i]+mark[bel[i]];
for(int i=st[bel[y]];i<=y;++i)
ans+=a[i]+mark[bel[i]];
for(int i=bel[x]+1;i<bel[y];++i)
ans+=sum[i]+mark[i]*siz[i];
}
return ans;
}
int main(){
// freopen("ans.out","w",stdout);
n=read(),m=read();
init(n);
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=sq;++i)
for(int j=st[i];j<=ed[i];++j)
sum[i]+=a[j];
while(m--){
pd=read(),x=read(),y=read();
if(pd==1){
k=read();
change(x,y,k);
}
else printf("%lld\n",query(x,y));
}
return 0;
}