分块板子求调
查看原帖
分块板子求调
358999
Emptyhanded楼主2023/5/1 21:27

我是fw

#include <iostream>
#include <cstdio>
#include <cmath>
#define int long long
int a[200005],b[5005],ans[5005],id[200005];
int T,n,len;
inline void update(int l,int r,int k) {
	int sid=id[l];
	int eid=id[r];
	if(sid==eid)
		for(int i=l;i<=r;i++) a[i]+=k,ans[sid]+=k;
	else {
		for(int i=l;id[i]==sid;i++) a[i]+=k,ans[sid]+=k;
		for(int i=r;id[i]==eid;i--) a[i]+=k,ans[eid]+=k;
		for(int i=sid+1;i<eid;i++) b[i]+=len*k,ans[i]+=len*k;
	}
}
inline int query(int l,int r) {
	int sid=id[l];
	int eid=id[r];
	int sum=0;
	if(sid==eid)
		for(int i=l;i<=r;i++) sum+=a[i]+b[sid];
	else {  
		for(int i=l;id[i]==sid;i++) sum+=a[i]+b[sid];
		for(int i=r;id[i]==eid;i--) sum+=a[i]+b[eid];
		for(int i=sid+1;i<eid;i++) sum+=ans[i];
	}return sum;
}
signed main() {
	scanf("%lld%lld",&n,&T);
	len=std::sqrt(n);
	for(int i=1;i<=n;i++) {
		scanf("%lld",&a[i]);
		id[i]=(i-1)/len+1;
	}
	while(T--) {
		int opt,l,r,k;
		scanf("%lld",&opt);
		if(opt==1) {
			scanf("%lld%lld%lld",&l,&r,&k);
			update(l,r,k);
		}
		if(opt==2) {
			scanf("%lld",&k);
			update(1,1,k);
		}
		if(opt==3) {
			scanf("%lld",&k);
			update(1,1,-k);
		}
		if(opt==4) {
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",query(l,r));
		}
		if(opt==5) printf("%lld\n",query(1,1));
	}
	return 0;
}
2023/5/1 21:27
加载中...