社区讨论

吉司机线段树TLE 80pts 求调

P6242【模板】线段树 3(区间最值操作、区间历史最值)参与者 3已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lwkaw9e1
此快照首次捕获于
2024/05/24 14:28
2 年前
此快照最后确认于
2024/05/24 18:16
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
namespace Fread{
const long long SIZE=1<<21;
	char buf[SIZE],*S,*T;
	inline char getchar(){
		if (S==T){
			T=(S=buf)+fread(buf,1,SIZE,stdin);
			if(S==T){
				return '\n';
			}
		}
		return *S++;
	}
}	
namespace Fwrite{
	const long long SIZE=1<<21;
	char buf[SIZE],*S=buf,*T=buf+SIZE;
	inline void flush(){
		fwrite(buf,1,S-buf,stdout);
		S=buf;
	}
	inline void putchar(char c){
		*S++=c;
		if(S==T){
			flush();
		}
	}
	struct NTR{
		~NTR(){
			flush();
		}
	}ztr;
} 
#ifdef ONLINE_JUDGE
#define getchar Fread::getchar
#define putchar Fwrite::putchar
#endif
namespace Fastio{
	struct Reader{
		template<typename T>
		Reader& operator>>(T& x){
			char c=getchar();
			T f=1;
			while (c<'0'||c>'9'){
				if (c=='-') f=-1;
				c=getchar();
			}
			x=0;
			while (c>='0'&&c<='9'){
				x=x*10+(c-'0');
				c=getchar();
			}
			x*=f;
			return *this;
		}
		Reader& operator>>(char& c){
			c=getchar();
			while (c==' '||c=='\n'){
				c=getchar();
			}
			return *this;
		}
		Reader& operator>>(char* str){
			long long len=0;
			char c=getchar();
			while (c==' '||c=='\n'){
				c=getchar();
			}
			while (c!=' '&&c!='\n'&&c!='\r'){ 
				str[len++]=c;
				c=getchar();
			}
			str[len]='\0';
			return *this;
		}
		Reader(){}
	}cin;
	const char endl='\n';
	struct Writer{
		template<typename T>
		Writer&operator<<(T x){
			if(x==0){
				putchar('0');
				return *this;
			}
			if(x<0){
				putchar('-');
				x=-x;
			}
			static long long sta[45];
			long long top=0;
			while(x){
				sta[++top]=x%10;
				x/=10;
			}
			while(top){
				putchar(sta[top]+'0');
				--top;
			}
			return *this;
		}
		Writer& operator<<(char c){
			putchar(c);
			return *this;
		}
		Writer& operator<<(char* str){
			long long cur=0;
			while(str[cur]){
				putchar(str[cur++]);
			}
			return *this;
		}
		Writer& operator<<(const char* str){
			long long cur=0;
			while(str[cur]){
				putchar(str[cur++]);
			}
			return *this;
		}
		Writer(){}
	}cout;
}
#define cin Fastio::cin
#define cout Fastio::cout
#define endl Fastio::endl
using namespace std;
int n,m,a[520010],op,l,r,k,v;
struct edge{
	int lef,rig;
	int Max,hisMax,nxtMax,Maxnum;
	long long sum=0;
	int lz1,hislz1,lz2,hislz2;
}tr[2200010];
inline void update(int id){
	int lefson=(id<<1),rigson=(id<<1|1); 
	tr[id].sum=tr[lefson].sum+tr[rigson].sum;
	tr[id].hisMax=max(tr[lefson].hisMax,tr[rigson].hisMax);
	if(tr[lefson].Max==tr[rigson].Max){
		tr[id].Max=tr[lefson].Max;
		tr[id].nxtMax=max(tr[lefson].nxtMax,tr[rigson].Max);
		tr[id].Maxnum=tr[lefson].Maxnum+tr[rigson].Maxnum;
	}
	else if(tr[lefson].Max>tr[rigson].Max){
		tr[id].Max=tr[lefson].Max;
		tr[id].nxtMax=max(tr[lefson].nxtMax,tr[rigson].Max);
		tr[id].Maxnum=tr[lefson].Maxnum;
	}
	else {
		tr[id].Max=tr[rigson].Max;
		tr[id].nxtMax=max(tr[lefson].Max,tr[rigson].nxtMax);
		tr[id].Maxnum=tr[rigson].Maxnum;
	}
}
inline void build(int id,int lef,int rig){
	tr[id].lef=lef;tr[id].rig=rig;
	if(lef==rig){
		tr[id].sum=tr[id].hisMax=tr[id].Max=a[lef];
		tr[id].nxtMax=INT_MIN;tr[id].Maxnum=1;
		return;
	}
	build(id<<1,lef,(lef+rig>>1));
	build(id<<1|1,(lef+rig>>1)+1,rig);
	update(id);
}
inline void fix(int id,int fixnum1,int hisfixnum1,int fixnum2,int hisfixnum2){
	tr[id].sum+=1ll*fixnum1*tr[id].Maxnum+1ll*fixnum2*(tr[id].rig-tr[id].lef+1-tr[id].Maxnum);
	tr[id].hisMax=max(tr[id].hisMax,tr[id].Max+hisfixnum1);
	tr[id].hislz1=max(tr[id].hislz1,tr[id].lz1+hisfixnum1);
	tr[id].hislz2=max(tr[id].hislz2,tr[id].lz2+hisfixnum2);
	tr[id].Max+=fixnum1;tr[id].lz1+=fixnum1;tr[id].lz2+=fixnum2;
	if(tr[id].nxtMax!=INT_MIN)tr[id].nxtMax+=fixnum2;
}
inline void pushdown(int id){
	int lefson=(id<<1),rigson=(id<<1|1); 
	int flag=max(tr[lefson].Max,tr[rigson].Max);
	if(tr[lefson].Max==flag)fix(lefson,tr[id].lz1,tr[id].hislz1,tr[id].lz2,tr[id].hislz2);
	else fix(lefson,tr[id].lz2,tr[id].hislz2,tr[id].lz2,tr[id].hislz2);
	if(tr[rigson].Max==flag)fix(rigson,tr[id].lz1,tr[id].hislz1,tr[id].lz2,tr[id].hislz2);
	else fix(rigson,tr[id].lz2,tr[id].hislz2,tr[id].lz2,tr[id].hislz2);
	tr[id].lz1=tr[id].lz2=tr[id].hislz1=tr[id].hislz2=0;
}
inline void modify1(int id,int lef,int rig,int fixnum){
	if(tr[id].lef>rig||tr[id].rig<lef)return;
	if(tr[id].lef>=lef&&tr[id].rig<=rig){
		fix(id,fixnum,fixnum,fixnum,fixnum);
		return;
	}
	pushdown(id);
	modify1(id<<1,lef,rig,fixnum);modify1(id<<1|1,lef,rig,fixnum);
	update(id);
}
inline void modify2(int id,int lef,int rig,int fixnum){
	if(tr[id].lef>rig||tr[id].rig<lef||fixnum>=tr[id].Max)return;
	if(tr[id].lef>=lef&&tr[id].rig<=rig&&fixnum>tr[id].nxtMax){
		fix(id,fixnum-tr[id].Max,fixnum-tr[id].Max,0,0);
		return;
	}
	pushdown(id);
	modify2(id<<1,lef,rig,fixnum);modify2(id<<1|1,lef,rig,fixnum);
	update(id);
}
inline long long query1(int id,int lef,int rig){
	if(tr[id].lef>rig||tr[id].rig<lef)return 0;
	if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].sum;
	pushdown(id);
	return query1(id<<1,lef,rig)+query1(id<<1|1,lef,rig);
}
inline int query2(int id,int lef,int rig){
	if(tr[id].lef>rig||tr[id].rig<lef)return INT_MIN;
	if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].Max;
	pushdown(id);
	return max(query2(id<<1,lef,rig),query2(id<<1|1,lef,rig));
}
inline int query3(int id,int lef,int rig){
	if(tr[id].lef>rig||tr[id].rig<lef)return INT_MIN;
	if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].hisMax;
	pushdown(id);
	return max(query3(id<<1,lef,rig),query3(id<<1|1,lef,rig));
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(1,1,n);
	while(m--){
		cin>>op>>l>>r;
		switch(op){
			case 1:
				cin>>k;modify1(1,l,r,k);
				break;
			case 2:
				cin>>v;modify2(1,l,r,v);
				break;
			case 3:
				cout<<query1(1,l,r)<<"\n";
				break;
			case 4:
				cout<<query2(1,l,r)<<"\n";
				break;
			case 5:
				cout<<query3(1,l,r)<<"\n";
				break;
		}
	}
} 

回复

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

正在加载回复...