前两个点wa,最后一个点TLE,用的是分块,帮忙调一下行吗QAQ(怀疑是区间查询有误)。主要是才初学,不太会,写的烂,题解又看不懂。。。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int q,n;
int a[200005],bl[200005],st[2005],en[2005],len[2005],sum[200005],blocknum,blocklen;
inline void init() {
blocklen=sqrt(n);
if(n%blocklen>0) blocklen+1;
else blocknum=blocklen;
for(register int i=1;i<=blocknum;i++) {
st[i]=(i-1)*blocklen+1;
en[i]=i*blocklen;
}
en[blocknum]=n;
for(register int i=1;i<=blocknum;i++) len[i]=en[i]-st[i]+1;
for(register int i=1;i<=blocknum;i++)
for(int j=st[i];j<=en[i];j++)
bl[j]=i;
}
inline int read() {
int x=0; bool y=false;
char ch=getchar();
while(ch<'0' || ch>'9') y=(ch=='-'),ch=getchar();
while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^'0'), ch=getchar();
return y?-x:x;
}
signed main(){
n=read(),q=read();
init();
for(register int i=1;i<=n;i++) {
a[i]=read();
}
while(q--) {
int opt,l,r,x;
opt=read();
if(opt==1) {
l=read(),r=read(),x=read();
if(bl[l]==bl[r]) {//在同一个块内
for(register int i=l;i<=r;i++) a[i]+=x;
}
else {
for(register int i=l;i<=en[bl[l]];i++) a[i]+=x;//最开始的块
for(register int i=bl[l]+1;i<=bl[r]-1;i++) sum[i]+=x;//中间的块
for(register int i=st[bl[r]];i<=r;i++) a[i]+=x;//最后的块
}
}
else if(opt==2){
x=read();
a[1]+=x;
}
else if(opt==3) {
x=read();
a[1]-=x;
}
else if(opt==4) {
l=read(),r=read();
int ans=0;
if(bl[l]==bl[r]) {//在同一个块内
for(register int i=l;i<=r;i++) ans+=a[i]+sum[i];
}
else {
for(register int i=l;i<=en[bl[l]];i++) ans+=a[i]+sum[i];//最开始的块
for(register int i=bl[l]+1;i<=bl[r]-1;i++) ans+=a[i]+sum[i];//中间的块
for(register int i=st[bl[r]];i<=r;i++) ans+=a[i]+sum[i];//最后的块
}
printf("%lld\n",ans);
}
else printf("%lld\n",a[1]+sum[1]);
}
return 0;
}