hdu 5306
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.
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.
For every operation of type 1 or 2, print one line containing the answer to the corresponding query.
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
5
15
3
12
吉如一的集训队论文讲得很清楚。存个模板。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1000010;
struct node{
int mx,mx1,l,r,cnt;
long long sum;
void sol(int x){
if(x>=mx) return;
sum-=(mx-x)*1ll*cnt;
mx=x;
}
}t[N*4];
int a[N],op,x,y,z,n,m,T;
void push_up(int k){
t[k].cnt=0;
t[k].sum=t[k*2].sum+t[k*2+1].sum;
t[k].mx=max(t[k*2].mx,t[k*2+1].mx);
t[k].mx1=max(t[k*2].mx1,t[k*2+1].mx1);
if(t[k*2].mx==t[k].mx) t[k].cnt+=t[k*2].cnt;
else t[k].mx1=max(t[k].mx1,t[k*2].mx);
if(t[k*2+1].mx==t[k].mx) t[k].cnt+=t[k*2+1].cnt;
else t[k].mx1=max(t[k].mx1,t[k*2+1].mx);
}
void push_down(int k){
t[k*2].sol(t[k].mx);
t[k*2+1].sol(t[k].mx);
}
void built(int k,int l,int r){
t[k].l=l; t[k].r=r;
if(l==r){
t[k].mx=t[k].sum=a[l];
t[k].mx1=-1; t[k].cnt=1;
return;
}
int mid=(l+r)>>1;
built(k*2,l,mid);
built(k*2+1,mid+1,r);
push_up(k);
}
void modify(int k,int l,int r,int x){
if(t[k].mx<=x) return;
if(t[k].l==l&&t[k].r==r&&t[k].mx1return;
}
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(l<=mid) modify(k*2,l,min(r,mid),x);
if(r>mid) modify(k*2+1,max(l,mid+1),r,x);
push_up(k);
}
int getmax(int k,int l,int r){
if(t[k].l==l&&t[k].r==r) return t[k].mx;
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) return getmax(k*2,l,r);
else if(l>mid) return getmax(k*2+1,l,r);
return max(getmax(k*2,l,mid),getmax(k*2+1,mid+1,r));
}
long long getsum(int k,int l,int r){
if(t[k].l==l&&t[k].r==r) return t[k].sum;
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) return getsum(k*2,l,r);
else if(l>mid) return getsum(k*2+1,l,r);
return getsum(k*2,l,mid)+getsum(k*2+1,mid+1,r);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i);
built(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&x,&y);
if(op==0) {
scanf("%d",&z);
modify(1,x,y,z);
}
else if(op==1) printf("%d\n",getmax(1,x,y));
else printf("%lld\n",getsum(1,x,y));
}
}
return 0;
}