我好像被卡空间了啊?
惨啊..
代码好丑啊QAQ
考虑更新
类似VEB Tree的记录当前最大值
不过这样子还是不容易更新最小值的 于是记录一个次大值 和最大值个数便于更新
对于最大值用类似方法维护
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
char c;
#define ll long long
bool flag;
inline void read(int&a)
{
a=0;do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
c=c=='-'?flag=true,getchar():c;
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
a=flag?flag=false,-a:a;
}
const
int INF=1<<29;
struct Seg
{
int maxtime,fmax,smax;
//int l,r;
int mintime,fmin,smin;
int maxtag,mintag,addtag;
ll sum;
Seg(){}
Seg(int data):
maxtag(-INF),fmax(data),smax(-INF),maxtime(1),
mintag(-INF),fmin(data),smin(INF),mintime(1),
addtag(0),sum(data)
//l(l),r(r)
{}
}T[2000001];
void Min(int&a,int b){a<b?a:a=b;}
void Max(int&a,int b){a>b?a:a=b;}
void MinTag(int place,int tag,int L,int R)
{
if(T[place].fmax<=tag)return;
T[place].sum-=(T[place].fmax-tag)*1ll*T[place].maxtime;
T[place].fmax=tag;
//Min(T[place].fmin,tag);
if(R-L+1==T[place].maxtime)
Min(T[place].fmin,tag);
else Min(T[place].smin,tag);
T[place].mintag=tag;
if(T[place].maxtag^-INF)
if(T[place].maxtag>T[place].mintag)
T[place].maxtag=T[place].mintag;
}
void MaxTag(int place,int tag,int L,int R)
{
if(T[place].fmin>=tag)return;
T[place].sum-=(T[place].fmin-tag)*1ll*T[place].mintime;
T[place].fmin=tag;
if(R-L+1==T[place].maxtime)
Max(T[place].fmax,tag);
else Max(T[place].smax,tag);
T[place].maxtag=tag;
if(T[place].mintag^-INF)
if(T[place].maxtag>T[place].mintag)
T[place].mintag=T[place].maxtag;
}
void AddTag(int place,int tag,int L,int R)
{
T[place].sum+=tag*1ll*(R-L+1);
T[place].fmax+=tag;
if(R-L+1!=T[place].maxtime)
T[place].smax+=tag;
T[place].fmin+=tag;
if(R-L+1!=T[place].maxtime)
T[place].smin+=tag;
//T[place].smin+=tag;
T[place].addtag+=tag;
if(T[place].maxtag!=-INF)
T[place].maxtag+=tag;
if(T[place].mintag!=-INF)
T[place].mintag+=tag;
}
void Push(int place,int L,int R)
{
int mid=L+R>>1;
if(T[place].addtag)
{
AddTag(place<<1,T[place].addtag,L,mid);
AddTag(place<<1|1,T[place].addtag,mid+1,R);
T[place].addtag=0;
}
if(T[place].maxtag^-INF)
{
MaxTag(place<<1,T[place].maxtag,L,mid);
MaxTag(place<<1|1,T[place].maxtag,mid+1,R);
T[place].maxtag=-INF;
}
if(T[place].mintag^-INF)
{
MinTag(place<<1,T[place].mintag,L,mid);
MinTag(place<<1|1,T[place].mintag,mid+1,R);
T[place].mintag=-INF;
}
}
void Up(int place)
{
T[place].maxtime=T[place].mintime=0;
int lc=place<<1,rc=lc|1;
T[place].sum=T[lc].sum+T[rc].sum;
if(T[lc].fmax==T[rc].fmax)
{
T[place].fmax=T[rc].fmax;
T[place].maxtime=T[lc].maxtime+T[rc].maxtime;
T[place].smax=max(T[lc].smax,T[rc].smax);
}
else if(T[lc].fmax>T[rc].fmax)
{
T[place].fmax=T[lc].fmax;
T[place].maxtime=T[lc].maxtime;
T[place].smax=max(T[lc].smax,T[rc].fmax);
}
else
{
T[place].fmax=T[rc].fmax;
T[place].maxtime=T[rc].maxtime;
T[place].smax=max(T[rc].smax,T[lc].fmax);
}
if(T[lc].fmin==T[rc].fmin)
{
T[place].fmin=T[rc].fmin;
T[place].mintime=T[lc].mintime+T[rc].mintime;
T[place].smin=min(T[lc].smin,T[rc].smin);
}
else if(T[lc].fmin<T[rc].fmin)
{
T[place].fmin=T[lc].fmin;
T[place].mintime=T[lc].mintime;
T[place].smin=min(T[lc].smin,T[rc].fmin);
}
else
{
T[place].fmin=T[rc].fmin;
T[place].mintime=T[rc].mintime;
T[place].smin=min(T[rc].smin,T[lc].fmin);
}
}
void MIN(int place,int l,int r,int p,int L,int R)
{
if(T[place].fmax<=p){return;}
if(L>=l&&R<=r&&T[place].fmax>p&&T[place].smax<p)
{return MinTag(place,p,L,R);}
Push(place,L,R);
int Mid=L+R>>1;
if(l<=Mid)MIN(place<<1,l,r,p,L,Mid);
if(r>Mid)MIN(place<<1|1,l,r,p,Mid+1,R);
Up(place);
}
void MAX(int place,int l,int r,int p,int L,int R)
{
if(T[place].fmin>=p){return;}
if(L>=l&&R<=r&&T[place].fmin<p&&T[place].smin>p)
{return MaxTag(place,p,L,R);}
Push(place,L,R);
int Mid=L+R>>1;
if(l<=Mid)MAX(place<<1,l,r,p,L,Mid);
if(r>Mid)MAX(place<<1|1,l,r,p,Mid+1,R);
Up(place);
}
void Add(int place,int l,int r,int tag,int L,int R)
{
if(L>=l&&R<=r)return AddTag(place,tag,L,R);
Push(place,L,R);
int mid=L+R>>1;
if(mid>=l)Add(place<<1,l,r,tag,L,mid);
if(mid<r)Add(place<<1|1,l,r,tag,mid+1,R);
Up(place);
}
ll Sum(int place,int l,int r,int L,int R)
{
if(L>=l&&R<=r)return T[place].sum;
Push(place,L,R);
int mid=L+R>>1;
ll res=0;
if(mid>=l)res+=Sum(place<<1,l,r,L,mid);
if(mid<r)res+=Sum(place<<1|1,l,r,mid+1,R);
return res;
}
int Querymin(int place,int l,int r,int L,int R)
{
if(L>=l&&R<=r)return T[place].fmin;
Push(place,L,R);
int mid=L+R>>1;
int res=INF;
if(mid>=l)Min(res,Querymin(place<<1,l,r,L,mid));
if(mid<r)Min(res,Querymin(place<<1|1,l,r,mid+1,R));
return res;
}
int Querymax(int place,int l,int r,int L,int R)
{
if(L>=l&&R<=r)return T[place].fmax;
int mid=L+R>>1;
Push(place,L,R);
int res=-INF;
if(mid>=l)Max(res,Querymax(place<<1,l,r,L,mid));
if(mid<r)Max(res,Querymax(place<<1|1,l,r,mid+1,R));
return res;
}
int Data[1000001];
void Build(int place,int l,int r)
{
T[place]=Seg(Data[l]);
if(l^r)
Build(place<<1,l,r+l>>1),Build(place<<1|1,1+(r+l>>1),r),Up(place);
}
void out(ll a)
{
if(a<0)putchar('-'),a=-a;
if(a>9)out(a/10);
putchar('0'+a%10);
}
int main()
{
int n,m;
read(n);
for(int i=1;i<=n;i++)read(Data[i]);
Build(1,1,n);
read(m);
while(m--)
{
/* //if(!m)
{puts(" ************** ");
puts(" ************** ");
puts(" ************** ");
puts(" ************** ");
Print(1,1,n);
puts(" ************** ");
puts(" ************** ");
puts(" ************** ");
puts(" ************** ");
puts(" ************** ");
}*/
int op;read(op);
int l,r,t;
read(l),read(r);
if(op==1)read(t),Add(1,l,r,t,1,n);
else if(op==2)read(t),MAX(1,l,r,t,1,n);
else if(op==3)read(t),MIN(1,l,r,t,1,n);
else if(op==4)out(Sum(1,l,r,1,n)),putchar('\n');
else if(op==5)out(Querymax(1,l,r,1,n)),putchar('\n');
else out(Querymin(1,l,r,1,n)),putchar('\n');
}
return 0;
}