Gorgeous Sequence

来源:互联网 发布:墨菲斯 知乎 编辑:程序博客网 时间:2024/06/10 17:19
There is a sequence aa of length nn. We use aiai to denote the ii-th element in this sequence. You should do the following three types of operations to this sequence. 

0 x y t0 x y t: For every xiyx≤i≤y, we use min(ai,t)min(ai,t) to replace the original aiai's value. 
1 x y1 x y: Print the maximum value of aiai that xiyx≤i≤y
2 x y2 x y: Print the sum of aiai that xiyx≤i≤y
Input
The first line of the input is a single integer TT, indicating the number of testcases. 

The first line contains two integers nn and mm denoting the length of the sequence and the number of operations. 

The second line contains nn separated integers a1,,ana1,…,an (1in,0ai<231∀1≤i≤n,0≤ai<231). 

Each of the following mm lines represents one operation (1xyn,0t<2311≤x≤y≤n,0≤t<231). 

It is guaranteed that T=100T=100n1000000, m1000000∑n≤1000000, ∑m≤1000000.
Output
For every operation of type 11 or 22, print one line containing the answer to the corresponding query. 
Sample Input
15 51 2 3 4 51 1 52 1 50 3 5 31 1 52 1 5
Sample Output
515312          

题解:建立一个sec[]记录第二大的元素,当Max>val>sec时,可以进行延迟修改。

#include<iostream>#include<stdio.h>#include<algorithm>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define root 1,n,1typedef long long ll;using namespace std;const int Maxn=1e6+10;int Max[Maxn<<2],sec[Maxn<<2],num[Maxn<<2];ll sum[Maxn<<2];void dec_tag(int rt,int val){    if(Max[rt]<=val) return;    sum[rt]-=1ll*num[rt]*(Max[rt]-val),Max[rt]=val;}void PushUp(int rt){    int l=rt<<1,r=rt<<1|1;    sum[rt]=sum[l]+sum[r];    sec[rt]=max(max(sec[l],sec[r]),Max[l]==Max[r]?0:min(Max[l],Max[r]));    Max[rt]=max(Max[l],Max[r]);    num[rt]=0;    if(Max[rt]==Max[l]) num[rt]+=num[l];    if(Max[rt]==Max[r]) num[rt]+=num[r];}void PushDown(int rt){    dec_tag(rt<<1,Max[rt]);    dec_tag(rt<<1|1,Max[rt]);}void Build(int l,int r,int rt){    sec[rt]=-1;    if(l==r){        scanf("%d",&Max[rt]);        sum[rt]=(long long)Max[rt];        num[rt]=1;        return;    }    int m=l+r>>1;    Build(lson);    Build(rson);    PushUp(rt);}void Updata(int L,int R,int val,int l,int r,int rt){    if(val>=Max[rt]) return;    if(L<=l&&r<=R&&val>sec[rt]){        dec_tag(rt,val);        return;    }    PushDown(rt);    int m=l+r>>1;    if(L<=m)        Updata(L,R,val,lson);    if(R>m)        Updata(L,R,val,rson);    PushUp(rt);}int QueryMax(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R) return Max[rt];    PushDown(rt);    int m=l+r>>1;    int ans=0;    if(L<=m)        ans=max(ans,QueryMax(L,R,lson));    if(R>m)        ans=max(ans,QueryMax(L,R,rson));    return ans;}ll QuerySum(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R) return sum[rt];    PushDown(rt);    int m=l+r>>1;    ll ans=0;    if(L<=m)        ans+=QuerySum(L,R,lson);    if(R>m)        ans+=QuerySum(L,R,rson);    return ans;}int main(){    int t,m,n;scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        Build(root);        while(m--){            int a,b,c,d;            scanf("%d",&a);            if(a==0){                scanf("%d%d%d",&b,&c,&d);                Updata(b,c,d,root);            }            else if(a==1){                scanf("%d%d",&b,&c);                printf("%d\n",QueryMax(b,c,root));            }            else{                scanf("%d%d",&b,&c);                printf("%lld\n",QuerySum(b,c,root));            }        }    }}