MnZn 求助,分块只过了最后一个点
查看原帖
MnZn 求助,分块只过了最后一个点
414386
Isshiki·Iroha楼主2021/12/10 23:36

删去了快读快输

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
const int maxlen=sqrt(maxn)+1;
int id[maxn],L[maxlen],R[maxlen],len;
ll a[maxn],btag[maxlen],sum[maxlen];
int n,f;
void make_block(){
	for(int i(1);i<=n;++i){
		id[i]=(i-1)/len+1;
		sum[id[i]]+=a[i];
	}
	for(int i(1);i<id[n];++i){
		L[i]=R[i-1]+1;
		R[i]=i*len;
	}
	L[id[n]]=R[id[n]-1]+1;
	R[id[n]]=n;
}
inline void modify(int l,int r,ll k){
	int idl=id[l],idr=id[r];
	if(idl==idr){
		for(int i(l);i<=r;++i){
			a[i]+=k;
		}
		return;
	}
	for(int i(l);i<=R[idl];++i){
		a[i]+=k;
		sum[idl]+=k;
	}
	for(int i(idl+1);i<idr;++i){
		btag[i]+=k;
		sum[i]+=k*len;
	}
	for(int i(r);i>=L[idr];--i){
		a[i]+=k;
		sum[idr]+=k;
	}
}
inline void add_main(ll k){
	a[1]+=k;
	sum[1]+=k;
}
inline void sub_main(ll k){
	a[1]-=k;
	sum[1]-=k;
}
inline ll query(int l,int r){
	int idl=id[l];
	int idr=id[r];
	ll ans=0;
	if(idl==idr){
		for(int i(l);i<=r;++i){
			ans+=a[i]+btag[idl];
		}
		return ans;
	}
	for(int i(l);i<=R[idl];++i){
		ans+=a[i]+btag[idl];
	}
	for(int i(idl+1);i<idr;++i){
		ans+=sum[i];
	}
	for(int i(r);i>=L[idr];--i){
		ans+=a[i]+btag[idr];
	}
	return ans;
}
inline ll query_main(){
	return a[1]+btag[1];
}
int main() {
	read<int>(n,f);
	len=sqrt(n);
	for(int i(1);i<=n;++i){
		read<ll>(a[i]);
	}
	make_block();
	ll k;
	for(int i(1),op,l,r;i<=f;++i){
		read<int>(op);
		if(op==1){
			read(l,r,k);
			modify(l,r,k);
		}
		else if(op==2){
			read<ll>(k);
			add_main(k);
		}
		else if(op==3){
			read<ll>(k);
			sub_main(k);
		}
		else if(op==4){
			read<int>(l,r);
			write<ll>(query(l,r));
			putc('\n');
		}
		else {
			write<ll>(query_main());
			putc('\n');
		}
	}
	flush();
	return 0;
}

2021/12/10 23:36
加载中...