分块求助,72分
查看原帖
分块求助,72分
924812
ys_kylin__楼主2023/8/11 15:27

前两个点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;
}
2023/8/11 15:27
加载中...