分块求调
查看原帖
分块求调
925818
hjhAKIOI楼主2024/7/8 16:58

本蒟蒻知道是线段树但是不会,只能写分块了QAQ

#include<iostream>
#include<cmath>
#include<cstring>
#define int long long
using namespace std;
const int N=2e5+5;
int n,a[N],L[N],R[N],pos[N],q,t,minn[N],add[N],space;

int read(){
	space=0;
	register int s=0,w=1;
	register char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') w=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		s=(s<<1)+(s<<3)+c-48;
		c=getchar();
	}
	if(c==' ') space=1;
	return s*w;
}

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

int ask(int l,int r){
	int p=pos[l],q=pos[r];
	int ans=0x3f3f3f3f;
	if(p==q){
		for(int i=l;i<=r;i++){
			ans=min(ans,a[i]+add[p]);
		}
		return ans;
	}
	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;
	}
}

signed main(){
	memset(minn,0x3f3f3f3f,sizeof(minn));
	cin>>n;
	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++){
			minn[i]=min(minn[i],a[j]);
			pos[j]=i;
		}
	}
	cin>>q;
	while(q--){
		int l,r,d;
		l=read();
		r=read();
		l++;
		r++;
		if(space){
			cin>>d;
			if(l>r){
				change(l,n,d);
				change(1,r,d);
			}
			else{
				change(l,r,d);
			}
		}
		else{
			if(l>r){
				cout<<min(ask(l,n),ask(1,r))<<endl;
			}
			else{
				cout<<ask(l,r)<<endl;
			}
		}
	}
	return 0;
}
2024/7/8 16:58
加载中...