最假女选手

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define Ls p->ls
#define Rs p->rs
#define mid ((l+r)>>1)
#define ll long long
#define Mx1 (p->mx1)
#define Mx2 (p->mx2)
#define Mn1 (p->mn1)
#define Mn2 (p->mn2)
#define Xnum (p->mxnum)
#define Nnum (p->mnnum)
#define Sm (p->sm)
#define La (p->laz)
#define Had (p->had)
struct tr{
	tr *ls,*rs;
	ll sm;
	int mx1,mx2;
	int mn1,mn2;
	int mxnum,mnnum;
	int laz;
	bool had;
}Tree[1<<20],*rt,*tl,*null;
const int inf=1e9+2e8,lim=1e9;
void Init()
{
	rt=tl=null=Tree;
	null->ls=null->rs=null;
	null->sm=0;
	null->mx1=null->mx2=-inf;
	null->mn1=null->mn2=inf;
}
const int Q=505555;
int a[Q];
void Update(tr *p)
{
	if(Ls->mx1==Rs->mx1)Mx1=Ls->mx1,Xnum=Ls->mxnum+Rs->mxnum,Mx2=max(Ls->mx2,Rs->mx2);
	else if(Ls->mx1>Rs->mx1)Mx1=Ls->mx1,Xnum=Ls->mxnum,Mx2=max(Ls->mx2,Rs->mx1);
	else Mx1=Rs->mx1,Xnum=Rs->mxnum,Mx2=max(Ls->mx1,Rs->mx2);
	//
	if(Ls->mn1==Rs->mn1)Mn1=Ls->mn1,Nnum=Ls->mnnum+Rs->mnnum,Mn2=min(Ls->mn2,Rs->mn2);
	else if(Ls->mn1<Rs->mn1)Mn1=Ls->mn1,Nnum=Ls->mnnum,Mn2=min(Ls->mn2,Rs->mn1);
	else Mn1=Rs->mn1,Nnum=Rs->mnnum,Mn2=min(Ls->mn1,Rs->mn2);
	//
	Sm=Ls->sm+Rs->sm;
}
void Init(tr *&p,int l,int r)
{
	p=++tl;
	La=0;
	Had=0;
	if(l==r){
		Ls=Rs=null;
		Sm=Mx1=Mn1=a[l];
		Mx2=-inf;
		Mn2=inf;
		Xnum=Nnum=1;
		return;
	}
	Init(Ls,l,mid);
	Init(Rs,mid+1,r);
	Update(p);
}
void PutDown(tr *p,int l,int r)
{
	if(!Had)return;
	int nv,xv;
	int del=La;
	La=0;Had=0;
	//
	Ls->had=1;
	Ls->laz+=del;
	Ls->mx1+=del;
	Ls->mx2+=del;
	Ls->mn1+=del;
	Ls->mn2+=del;
	Ls->sm+=1LL*(mid-l+1)*del;
	nv=Ls->mn1,xv=Ls->mx1;
	if(Ls->mx2>-lim)Ls->mx2=min(max(Ls->mx2,Mn1),Mx1);
	Ls->mx1=min(max(Ls->mx1,Mn1),Mx1);
	if(Ls->mn2<lim)Ls->mn2=min(max(Ls->mn2,Mn1),Mx1);
	Ls->mn1=min(max(Ls->mn1,Mn1),Mx1);
	Ls->sm+=1LL*Ls->mxnum*(Ls->mx1-xv);
	if(Ls->mx1!=Ls->mn1)Ls->sm+=1LL*Ls->mnnum*(Ls->mn1-nv);
	//
	Rs->had=1;
	Rs->laz+=del;
	Rs->mx1+=del;
	Rs->mx2+=del;
	Rs->mn1+=del;
	Rs->mn2+=del;
	Rs->sm+=1LL*(r-mid)*del;
	nv=Rs->mn1,xv=Rs->mx1;
	if(Rs->mx2>-lim)Rs->mx2=min(max(Rs->mx2,Mn1),Mx1);
	Rs->mx1=min(max(Rs->mx1,Mn1),Mx1);
	if(Rs->mn2<lim)Rs->mn2=min(max(Rs->mn2,Mn1),Mx1);
	Rs->mn1=min(max(Rs->mn1,Mn1),Mx1);
	Rs->sm+=1LL*Rs->mxnum*(Rs->mx1-xv);
	if(Rs->mx1!=Rs->mn1)Rs->sm+=1LL*Rs->mnnum*(Rs->mn1-nv);
}
void MDF(tr *p,int l,int r,int x,int y,int ty,int v)
{
	if(x<=l&&y>=r)
	{
		if(ty==1){
			Mx1+=v;
			Mx2+=v;
			Mn1+=v;
			Mn2+=v;
			Sm+=1LL*(r-l+1)*v;
			La+=v;
			Had=1;
			return;
		}
		if(ty==2){
			if(v<=Mn1)return;
			if(v<Mn2){
				Had=1;
				Sm+=1LL*Nnum*(v-Mn1);
				if(Nnum==r-l+1){
					Mn1=Mx1=v;
					return;
				}
				if(Nnum+Xnum==r-l+1){
					Mn1=Mx2=v;
					return;
				}
				Mn1=v;
				return;
			}
		}
		if(ty==3){
			if(v>=Mx1)return;
			if(l==r){
				Sm=Mx1=Mn1=min(v,Mx1);
				return;
			}
			if(v>Mx2){
				Had=1;
				Sm-=1LL*Xnum*(Mx1-v);
				if(Xnum==r-l+1){
					Mn1=Mx1=v;
					return;
				}
				if(Nnum+Xnum==r-l+1){
					Mx1=Mn2=v;
					return;
				}
				Mx1=v;
				return;
			}
		}
	}
	PutDown(p,l,r);
	if(x<=mid)MDF(Ls,l,mid,x,y,ty,v);
	if(y>mid)MDF(Rs,mid+1,r,x,y,ty,v);
	Update(p);
}
int GX(tr *p,int l,int r,int x,int y)
{
	if(x<=l&&y>=r)return Mx1;
	PutDown(p,l,r);
	if(x>mid)return GX(Rs,mid+1,r,x,y);
	if(y<=mid)return GX(Ls,l,mid,x,y);
	return max(GX(Ls,l,mid,x,y),GX(Rs,mid+1,r,x,y));
}
int GN(tr *p,int l,int r,int x,int y)
{
	if(x<=l&&y>=r)return Mn1;
	PutDown(p,l,r);
	if(x>mid)return GN(Rs,mid+1,r,x,y);
	if(y<=mid)return GN(Ls,l,mid,x,y);
	return min(GN(Ls,l,mid,x,y),GN(Rs,mid+1,r,x,y));
}
ll GS(tr *p,int l,int r,int x,int y)
{
	if(x<=l&&y>=r)return Sm;
	PutDown(p,l,r);
	if(x>mid)return GS(Rs,mid+1,r,x,y);
	if(y<=mid)return GS(Ls,l,mid,x,y);
	return GS(Ls,l,mid,x,y)+GS(Rs,mid+1,r,x,y);
}
char *p1,*p2,buf[1<<20];
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
inline int R(){
	int t=0;
	char o=GC;
	bool fl=0;
	while(o>57||o<48){
		if(o=='-')fl=1;
		o=GC;
	}
	while(o>47&&o<58)t=(t<<1)+(t<<3)+o-48,o=GC;
	return fl?-t:t;
}
int main()
{
	int n,m;
	n=R();
	for(int i=1;i<=n;i++)
		a[i]=R();
	Init();
	Init(rt,1,n);
	int ty,x,y;
	for(m=R();m;--m){
		ty=R(),x=R(),y=R();
		if(ty<=3)MDF(rt,1,n,x,y,ty,R());
		else{
			if(ty==4)printf("%lld\n",GS(rt,1,n,x,y));
			if(ty==5)printf("%d\n",GX(rt,1,n,x,y));
			if(ty==6)printf("%d\n",GN(rt,1,n,x,y));
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值