分块WA76(第19和第21个点未过)
查看原帖
分块WA76(第19和第21个点未过)
723954
yhyz2021017楼主2023/12/16 14:17
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5;
ll n,m,op,a,b,k,num[N];
ll B,l[N],r[N],bel[N],sz[N],cnt[N],f[N];
void init(){
	B=sqrt(n);
	for(int i=1;i<=B;++i) {
		l[i]=(i-1)*B+1,r[i]=i*B,sz[i]=B;
	}
	if(r[B]!=n) {
		++B,l[B]=r[B-1]+1,r[B]=n,sz[B]=n-r[B-1];
	}
	for(int i=1;i<=B;++i) 
		for(ll j=l[i];j<=r[i];j++) {
			bel[j]=i;
		}
}
void add(int i,ll k) {
	num[i]+=k;
	cnt[bel[i]]+=k;
}
void change(ll a,ll b,ll k) {
	if(bel[a]==bel[b]) {
		for(int i=a;i<=b;++i) add(i,k);
		return;
	}
	for(int i=a;i<=r[bel[a]];++i) add(i,k);
	for(int i=l[bel[b]];i<=b;++i) add(i,k);
	for(int i=bel[a]+1;i<bel[b];++i) {	
		f[i]+=k;cnt[i]+=k*sz[i];
	}
}
ll sum(ll a,ll b) {
	ll res=0;
	if(bel[a]==bel[b]) {
		for(int i=a;i<=b;++i) res+=num[i]+f[bel[i]];
		return res;
	}
	for(int i=a;i<=r[bel[a]];++i) res+=num[i]+f[bel[i]];
	for(int i=l[bel[b]];i<=b;++i) res+=num[i]+f[bel[i]];
	for(int i=bel[a]+1;i<bel[b];++i) res+=cnt[i];
	return res;
}
int main() {
	scanf("%lld%lld",&n,&m);
	init();
	for(ll i=1;i<=n;++i) {
		scanf("%lld",&num[i]);
		cnt[bel[i]]+=num[i];
	}	
	while(m--) {
		scanf("%lld",&op);
		if(op<=3) {
			if(op==1) {
				scanf("%lld%lld%lld",&a,&b,&k);
				change(a,b,k);
			}else{
				scanf("%lld",&k);
				change(1,1,op==2 ? k : -k);
			}
		}else{
			if(op==4) {
				scanf("%lld%lld",&a,&b);
				printf("%lld\n",sum(a,b));
			}else{
				printf("%lld\n",num[1]+f[1]);
			}
		}
	}
	return 0;
}
2023/12/16 14:17
加载中...