Gorgeous Sequence
Problem Description
There is a sequence a of length n. We use ai to denote the i-th element in this sequence. You should do the following three types of operations to this sequence.
0 x y t: For every x≤i≤y, we use min(ai,t) to replace the original ai’s value.
1 x y: Print the maximum value of ai that x≤i≤y.
2 x y: Print the sum of ai that x≤i≤y.
Input
The first line of the input is a single integer T, indicating the number of testcases.
The first line contains two integers n and m denoting the length of the sequence and the number of operations.
The second line contains n separated integers a1,…,an (∀1≤i≤n,0≤ai<231).
Each of the following m lines represents one operation (1≤x≤y≤n,0≤t<231).
It is guaranteed that T=100, ∑n≤1000000, ∑m≤1000000.
Output
For every operation of type 1 or 2, print one line containing the answer to the corresponding query.
Sample Input
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
Sample Output
5
15
3
12
#include
#include
#include
using namespace std;
#define N 1000010
#define LL long long
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
int t,n,m;
int mx[N<<2],se[N<<2],nm[N<<2];
LL sum[N<<2];
void pushup(int rt)
{
nm[rt]=0;
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
se[rt]=max(se[rt<<1],se[rt<<1|1]);
if(mx[rt]==mx[rt<<1]) nm[rt]+=nm[rt<<1];
else se[rt]=max(se[rt],mx[rt<<1]);
if(mx[rt]==mx[rt<<1|1]) nm[rt]+=nm[rt<<1|1];
else se[rt]=max(se[rt],mx[rt<<1|1]);
}
void pushdown(int rt)
{
if(mx[rt]1])
{
sum[rt<<1]-=(LL)nm[rt<<1]*(mx[rt<<1]-mx[rt]);
mx[rt<<1]=mx[rt];
}
if(mx[rt]1|1])
{
sum[rt<<1|1]-=(LL)nm[rt<<1|1]*(mx[rt<<1|1]-mx[rt]);
mx[rt<<1|1]=mx[rt];
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
scanf("%I64d",&sum[rt]);
mx[rt]=sum[rt];nm[rt]=1;
se[rt]=-1;
return;
}
int m=(l+r)>>1;
build(lson);build(rson);
pushup(rt);
}
int query_max(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r) return mx[rt];
pushdown(rt);
int m=(l+r)>>1,ret=0;
if(L<=m) ret=max(ret,query_max(lson,L,R));
if(R>m) ret=max(ret,query_max(rson,L,R));
return ret;
}
LL query_sum(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r) return sum[rt];
pushdown(rt);
int m=(l+r)>>1;LL ret=0;
if(L<=m) ret+=query_sum(lson,L,R);
if(R>m) ret+=query_sum(rson,L,R);
return ret;
}
void update(int rt,int l,int r,int L,int R,int val)
{
if(val>=mx[rt]) return;
if(L<=l&&R>=r&&val>se[rt])
{
sum[rt]-=(LL)nm[rt]*(mx[rt]-val);
mx[rt]=val;
return;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(lson,L,R,val);
if(R>m) update(rson,L,R,val);
pushup(rt);
}
int main()
{
for(scanf("%d",&t);t;--t)
{
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--)
{
int opt,l,r;
scanf("%d%d%d",&opt,&l,&r);
if(opt==0)
{
int val;scanf("%d",&val);
update(1,1,n,l,r,val);
}
if(opt==1)
{
printf("%d\n",query_max(1,1,n,l,r));
}
if(opt==2)
{
printf("%I64d\n",query_sum(1,1,n,l,r));
}
}
}
return 0;
}
/*
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
*/