分块求调,本地ac,提交全wa
查看原帖
分块求调,本地ac,提交全wa
574916
SunsetLake楼主2023/7/15 07:54

rt,有没有大佬知道这是什么情况,或者帮我找一下代码哪里写错了,感激不尽!

Input
8 10
640 591 141 307 942 58 775 133 
2 1 5
2 3 8
2 3 6
2 5 8
2 4 8
1 4 8 60
2 1 6
2 5 8
1 3 7 15
1 2 6 86
Output
2621
2356
1448
1908
2215
2859
2148

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,op,t,x,y,k;
ll a[100005],l[100005],r[100005],sum[100005],ad[100005],pos[100005];//l,r是每个块的左右端点;sum区间和,ad懒标记,pos是块号 
void update(int x,int y,ll d){
	int p=pos[x],q=pos[y];
	if(p==q){
		for(int i=x;i<=y;++i)a[i]+=d;
		sum[p]+=d*(ll)(y-x+1);
		return;
	}
	for(int i=p+1;i<=q-1;++i)ad[i]+=d;
	
	for(int i=x;i<=r[p];++i)a[i]+=d;
	sum[p]+=d*(r[p]-x+1);
	for(int i=l[q];i<=y;++i)a[i]+=d;
	sum[q]+=d*(y-l[q]+1);
}
ll query(int x,int y){
	int p=pos[x],q=pos[y];
	ll res=0;
	if(p==q){
		for(int i=x;i<=y;++i)res+=a[i];
		res+=ad[p]*(y-x+1);
		return res;
	}
	for(int i=p+1;i<=q-1;++i)res+=sum[i]+ad[i]*(r[i]-l[i]+1);
	for(int i=x;i<=r[p];++i)res+=a[i];
	res+=ad[p]*(r[p]-x+1);
	for(int i=l[q];i<=y;++i)res+=a[i];
	res+=ad[q]*(y-l[q]+1);
	return res;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
	t=sqrt(n);
	for(int i=1;i<=t;++i){
		l[i]=(i-1)*t+1;
		r[i]=i*t;
	}
	if(r[t]<n){
		l[++t]=r[t-1]+1;
		r[t]=n;
	}
	for(int i=1;i<=t;++i){
		for(int j=l[i];j<=r[i];++j){
			sum[i]+=a[j];
			pos[j]=i;
		}
	}
	while(m--){
		scanf("%d%d%d",&op,&x,&y);
		if(op==1){
			scanf("%lld",&k);
			update(x,y,k);
		}
		else printf("%lld\n",query(x,y));
	}
	return 0;
}
2023/7/15 07:54
加载中...