分块求调30pts
查看原帖
分块求调30pts
538821
m1kusama楼主2023/3/9 13:17
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int belong[100005],a[100005],s[1000],l[1000],r[1000],lazy[1000];
int len,num;

void init(){
	len=sqrt(n),num=(n-1)/len+1;
	for(int i=1;i<=n;i++){
		cin>>a[i];	
	}
	for(int i=1;i<=num;i++){
		for(int j=1;j<=len;j++){
			s[i]+=a[j+(i-1)*len];
			belong[j+(i-1)*len]=i;
		}
		l[i]=r[i-1]+1;
		r[i]=i*len;
	}
}


void plus_(int x,int y,int k){
	int bx=belong[x];
	int by=belong[y];
	if(bx==by){
		for(int i=x;i<=y;i++){
			a[i]+=k;
		}
		s[bx]+=k*(y-x+1);
		return;
	}else{
		for(int i=x;i<=r[bx];i++){
				a[i]+=k;
		}
		s[bx]+=k*(r[bx]-x+1);
		for(int i=bx+1;i<by;i++){
			lazy[i]+=k;
			s[i]+=k*len;
		}
		for(int i=l[by];i<=y;i++){
			a[i]+=k;
		}
		s[by]+=k*(y-l[by]+1);
		return;
	}
}


int query(int x,int y){
	int bx=belong[x];
	int by=belong[y];
	int ans=0;
	if(bx==by){
		for(int i=x;i<=y;i++){
			ans+=a[i];
		}			
		if(lazy[bx]!=0) ans+=lazy[bx]*(y-x+1);
		return ans;
	}else{
		for(int i=x;i<=r[bx];i++){
				ans+=a[i];
		}
		if(lazy[bx]!=0) ans+=lazy[bx]*(r[bx]-x+1);
		for(int i=bx+1;i<by;i++){
			ans+=s[i];
			if(lazy[i]!=0) ans+=lazy[bx]*len;
		}
		for(int i=l[by];i<=y;i++){
			ans+=a[i];
 		}
		if(lazy[by]!=0) ans+=lazy[by]*(y-l[by]+1);
		return ans;
		}
}


signed main(){
	cin>>n>>m;
	init();
	for(int i=0;i<m;i++){
		int opt,x,y,k;
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>k;
			plus_(x,y,k);
		}else{
			cin>>x>>y;
			cout<<query(x,y)<<endl;
		}
	}
	return 0;
}
2023/3/9 13:17
加载中...