社区讨论

不求调,求hack(悬关)

P1253扶苏的问题参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo18aurd
此快照首次捕获于
2023/10/22 16:50
2 年前
此快照最后确认于
2023/11/02 16:40
2 年前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
const int MINN=-1000000000000000001;
int n,q,a[N],num,in[N],lt[N],rt[N],maxn[N],ch[N],past[N];
void block(){
	num=sqrt(n);
	if(num*num!=n) ++num;
	int lar=num;
	if(num*(num-1)>=n&&num*num!=n) --lar;
	for(int i=1;i<num;i++){
		lt[i]=rt[i-1]+1;
		rt[i]=i*lar;
	}
	lt[num]=rt[num-1]+1;
	rt[num]=n;
	for(int i=1;i<=rt[num-1];i++){
		in[i]=(i-1)/lar+1;
	}
	for(int i=lt[num];i<=n;i++){
		in[i]=num;
	}
	for(int i=1;i<=num;i++){
		ch[i]=MINN;
	}
	for(int i=1;i<=num;i++){
		maxn[i]=MINN;
		for(int j=lt[i];j<=rt[i];j++){
			maxn[i]=max(maxn[i],a[j]);
		}
	}
}
void update1(int l,int r,int x){
	if(l==lt[in[l]]&&r==rt[in[r]]){
		past[in[l]]=0;
		ch[in[l]]=x;
		maxn[in[l]]=x;
		return;
	}
	if(ch[in[l]]!=MINN){
		ch[in[l]]+=past[in[l]];
		maxn[in[l]]=max(ch[in[l]],x);
		for(int i=lt[in[l]];i<l;i++){
			a[i]=ch[in[i]];
		}
		for(int i=l;i<=r;i++){
			a[i]=x;
		}
		for(int i=r+1;i<=rt[in[r]];i++){
			a[i]=ch[in[i]];
		}
		ch[in[l]]=MINN;
		past[in[l]]=0;
		return;
	}
	maxn[in[l]]=x;
	for(int i=lt[in[l]];i<l;i++){
		maxn[in[i]]=max(maxn[in[i]],a[i]+past[in[i]]);
	}
	for(int i=l;i<=r;i++){
		a[i]=x;
	}
	for(int i=r+1;i<=rt[in[r]];i++){
		maxn[in[i]]=max(maxn[in[i]],a[i]+past[in[i]]);
	}
	past[in[l]]=0;
}
void change(int l,int r,int x){
	if(in[l]==in[r]){
		update1(l,r,x);
		return;
	}
	update1(l,rt[in[l]],x);
	update1(lt[in[r]],r,x);
	for(int i=in[l]+1;i<in[r];i++){
		past[i]=0;
		ch[i]=x;
		maxn[i]=x;
	}
}
void update2(int l,int r,int x){
	if(l==lt[in[l]]&&r==rt[in[r]]){
		past[in[l]]+=x;
		maxn[in[l]]+=x;
		return;
	}
	if(ch[in[l]]!=MINN){
		maxn[in[l]]+=x;
		for(int i=lt[in[l]];i<l;i++){
			a[i]=ch[in[l]];
		}
		for(int i=l;i<=r;i++){
			a[i]=ch[in[l]]+x;
		}
		for(int i=r+1;i<=rt[in[r]];i++){
			a[i]=ch[in[l]];
		}
		ch[in[l]]=MINN;
		return;
	}
	maxn[in[l]]=MINN;
	for(int i=lt[in[l]];i<l;i++){
		maxn[in[i]]=max(maxn[in[i]],a[i]+past[in[i]]);
	}
	for(int i=l;i<=r;i++){
		a[i]+=x;
		maxn[in[i]]=max(maxn[in[i]],a[i]+past[in[i]]);
	}
	for(int i=r+1;i<=rt[in[r]];i++){
		maxn[in[i]]=max(maxn[in[i]],a[i]+past[in[i]]);
	}
}
void pastsum(int l,int r,int x){
	if(in[l]==in[r]){
		update2(l,r,x);
		return;
	}
	update2(l,rt[in[l]],x);
	update2(lt[in[r]],r,x);
	for(int i=in[l]+1;i<in[r];i++){
		past[i]+=x;
		maxn[i]+=x;
	}
}
int query(int l,int r){
	if(ch[in[l]]!=MINN) return ch[in[l]]+past[in[l]];
	int res=MINN;
	for(int i=l;i<=r;i++){
		res=max(res,a[i]+past[in[i]]);
	}
	return res;
}
int ask(int l,int r){
	if(in[l]==in[r]) return query(l,r);
	int res=max(query(l,rt[in[l]]),query(lt[in[r]],r));
	for(int i=in[l]+1;i<in[r];i++){
		res=max(res,maxn[i]);
	}
	return res;
}
inline int read(){
	int s=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=(s<<3)+(s<<1)+(ch^48);
		ch=getchar();
	}
	return s*f;
}
signed main(){
	n=read(),q=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	block();
	for(int i=1;i<=q;i++){
		int op=read(),l=read(),r=read();
		if(op==1){
			int x=read();
			change(l,r,x);
			continue;
		}
		if(op==2){
			int x;cin>>x;
			pastsum(l,r,x);
			continue;
		}
		printf("%lld\n",ask(l,r));
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...