分块80分求助,最后一个点TLE
  • 板块P2357 守墓人
  • 楼主Tjqq
  • 当前回复7
  • 已保存回复7
  • 发布时间2022/10/22 22:00
  • 上次更新2023/10/27 06:25:14
查看原帖
分块80分求助,最后一个点TLE
540665
Tjqq楼主2022/10/22 22:00
#include<cstdio>
#include<cmath>
#define re register
#define int long long
#define ull unsigned long long
#define INF_INT 0x3f3f3f3f
#define INF_LL 0x7fffffffffffffff
const int N=3e5;
using namespace std;
char c;
int flag;
inline void rd(re int &x){
	x=0,flag=1;
	c=getchar();
	while((c<'0'||c>'9')&&c!='-')c=getchar();
	if(c=='-')flag=-1,c=getchar();
	while(c>='0'&&c<='9'){
		x=(x<<1)+(x<<3)+c-48;
		c=getchar(); 
	} 
	x*=flag;
}
int n,Q,f,x,y,val,block,num,p,q,ans;
int a[N],bl[N],l[N],r[N],sum[N],add[N];
void build(){
	block=sqrt(n);
	num=n/block+(n%block);
	for(int i=1;i<=n;i++)
		bl[i]=(i-1)/block+1,sum[bl[i]]+=a[i];
	for(int i=1;i<=num;i++)
		l[i]=(i-1)*block,r[i]=i*block;
	r[num]=n;
}
inline void update(){
	p=bl[x],q=bl[y];
	if(p==q){
		for(int i=x;i<=y;i++)
			a[i]+=val,sum[p]+=val;
		return ;
	}
	for(int i=p+1;i<=q-1;i++)
		add[i]+=val;
	for(int i=x;i<=r[p];i++)
		sum[i]+=val;
	for(int i=l[q];i<=y;i++)
		sum[i]+=val;
}
inline int ask(){
	ans=0;
	p=bl[x],q=bl[y];
	if(p==q){
		for(int i=x;i<=y;i++)
			ans+=a[i];
		ans+=(y-x+1)*add[p];
		return ans;
	}
	for(int i=p+1;i<=q-1;i++)
		ans+=(sum[i]+add[i]*block);
	for(int i=x;i<=r[p];i++)
		ans+=(a[i]+add[p]);
	for(int i=l[q];i<=y;i++)
		ans+=(a[i]+add[q]);
	return ans;
}
signed main(){
	rd(n),rd(Q);
	for(int i=1;i<=n;i++)rd(a[i]);
	while(Q--){
		rd(f);
		if(f==1){
			rd(x),rd(y),rd(val);
			update();
		}
		else if(f==2){
			rd(val);
			a[1]+=val,sum[1]+=val;
		}
		else if(f==3){
			rd(val);
			a[1]-=val,sum[1]-=val;
		}
		else if(f==4){
			rd(x),rd(y);
			printf("%lld\n",ask());
		}
		else printf("%lld\n",a[1]+add[1]);
	}
	return 0;
}
2022/10/22 22:00
加载中...