分块求调(AC on#1)
查看原帖
分块求调(AC on#1)
925818
hjhAKIOI楼主2024/4/4 16:23

看数据范围不大并且本蒟蒻不会线段树就写了分块

#include<iostream>
#include<cmath>
#include<cstring>
#define int unsigned long long
using namespace std;
const int N=2e6+5;
int a[N],sum[N],add[N],minn[N];
int L[N],R[N];
int pos[N];
int n,m,t,result;

void change(int l,int r,int d){
	int p=pos[l],q=pos[r];
	if(p==q){
		result=4e18;
		for(int i=l;i<=r;i++){
			a[i]+=d;
		}
		for(int i=L[p];i<=R[p];i++){
			result=min(result,a[i]);
		}
		minn[p]=result;
		sum[p]+=(r-l+1)*d;
	}
	else{
		for(int i=p+1;i<=p-1;i++){
			add[i]+=d;
		}
		result=4e18;
		for(int i=l;i<=R[p];i++){
			a[i]+=d;
		}
		for(int i=L[p];i<=R[p];i++){
			result=min(result,a[i]);
		}
		minn[p]=result;
		sum[p]+=(R[p]-l+1)*d;
		result=4e18;
		for(int i=L[q];i<=r;i++){
			a[i]+=d;
		}
		for(int i=L[q];i<=R[q];i++){
			result=min(result,a[i]);
		}
		minn[q]=result;
		sum[q]+=(r-L[q]+1)*d;
	}
}

int ask_min(int l,int r){
	int p=pos[l],q=pos[r];
	int ans=4e18;
	if(p==q){
		for(int i=l;i<=r;i++){
			ans=min(ans,a[i]+add[p]);
		}
	}
	else{
		for(int i=l;i<=R[p];i++){
			ans=min(ans,a[i]+add[p]);
		}
		for(int i=p+1;i<=q-1;i++){
			ans=min(ans,minn[i]+add[i]);
		}
		for(int i=L[q];i<=r;i++){
			ans=min(ans,a[i]+add[q]);
		}
	}
	return ans;
}

int ask_sum(int l,int r){
	int p=pos[l],q=pos[r];
	int ans=0;
	if(p==q){
		for(int i=l;i<=r;i++){
			ans+=a[i];
		}
		ans+=(r-l+1)*add[p];
	}
	else{
		for(int i=p+1;i<=q-1;i++){
			ans+=sum[i]+(R[i]-L[i]+1)*add[i];
		}
		for(int i=l;i<=R[p];i++){
			ans+=a[i];
		}
		ans+=(R[p]-l+1)*add[p];
		for(int i=L[q];i<=r;i++){
			ans+=a[i];
		}
		ans+=(r-L[q]+1)*add[q];
	}
	return ans;
}

signed main(){
	memset(minn,4e18,sizeof(minn));
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>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){
		t++;
		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++){
			pos[j]=i;
			sum[i]+=a[j];
			minn[i]=min(minn[i],a[j]);
		}
	}
	while(m--){
		char op;
		int l,r,d;
		cin>>op>>l>>r;
		if(op=='M'){
			cout<<ask_min(l,r)<<endl;
		}
		if(op=='S'){
			cout<<ask_sum(l,r)<<endl;
		}
		if(op=='P'){
			cin>>d;
			change(l,r,d);
		}
	}
	return 0;
}

2024/4/4 16:23
加载中...