分块裸题
然后就是记得左右边界处理和分块的初始化
忘了初始化会被卡成暴力
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; int a[50001],belong[50001],lm[50001],rm[50001],num,sz,tag[50001],n; inline int qread(void){ int x=0; int f=1; char s; s=getchar(); while((s>'9'||s<'0')&&s!='-') s=getchar(); if(s=='-'){ f=-1; s=getchar(); } while(s>='0'&&s<='9'){ x*=10; x+=s-'0'; s=getchar(); } return x*f; } void calbe(int n){ for(int i=1;i<=n;i++) belong[i]=((i-1)/sz)+1; } void modify(int l,int r,int w){ int xsl=belong[l]; int xsr=belong[r]; for(int i=l;i<=min(sz*xsl,r);i++) a[i]+=w; if(xsl!=xsr){ for(int i=(xsr-1)*sz+1;i<=r;i++) a[i]+=w; for(int i=xsl+1;i<=xsr-1;i++) tag[i]+=w; } } int query(int r){ return a[r]+tag[belong[r]]; } int main(){ n=qread(); sz=sqrt(n); calbe(n); for(int i=1;i<=n;i++) a[i]=qread(); for(int i=1;i<=n;i++){ int mode,l,r,c; mode=qread(); if(mode==0){ l=qread(); r=qread(); c=qread(); modify(l,r,c); } else{ l=qread(); r=qread(); c=qread(); printf("%d ",query(r)); } } return 0; }