There is a sequence x≤i≤y. 

InputThe first line of the input is a single integer 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

题意:三种操作,0区间min操作;1区间求max;2区间求和。

思路:segments tres beats模板题。 因为都是区间操作,所以有很多相同的值,我们记录每个区间的最大值,最大值的数量,以及第二大值。然后就可以搞了,不用lazy,下推的时候如果mx[Now]比儿子还小,那么久自然的下推即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000010;
int mx[maxn<<2],mc[maxn<<2],se[maxn<<2];
ll sum[maxn<<2];
void pushdown(int Now)
{
    if(mx[Now]<mx[Now<<1]){
        sum[Now<<1]-=(ll)(mx[Now<<1]-mx[Now])*mc[Now<<1];
        mx[Now<<1]=mx[Now];
    }
    if(mx[Now]<mx[Now<<1|1]){
        sum[Now<<1|1]-=(ll)(mx[Now<<1|1]-mx[Now])*mc[Now<<1|1];
        mx[Now<<1|1]=mx[Now];
    }
}
void pushup(int Now)
{
    sum[Now]=sum[Now<<1]+sum[Now<<1|1];
    mx[Now]=max(mx[Now<<1],mx[Now<<1|1]);
    if(mx[Now<<1]==mx[Now<<1|1]){
        mc[Now]=mc[Now<<1]+mc[Now<<1|1];
        se[Now]=max(se[Now<<1],se[Now<<1|1]);
    }
    else {
        if(mx[Now<<1]>mx[Now<<1|1]){
            mc[Now]=mc[Now<<1];
            se[Now]=max(mx[Now<<1|1],se[Now<<1]);
        }
        else {
            mc[Now]=mc[Now<<1|1];
            se[Now]=max(mx[Now<<1],se[Now<<1|1]);
        }
    }
}
void build(int Now,int L,int R)
{
    if(L==R){
        scanf("%d",&mx[Now]);
        sum[Now]=mx[Now]; se[Now]=0;
        mc[Now]=1;  return ;
    }
    int Mid=(L+R)>>1;
    build(Now<<1,L,Mid); build(Now<<1|1,Mid+1,R);
    pushup(Now);
}
ll querysum(int Now,int L,int R,int l,int r){
    if(l<=L&&r>=R) return sum[Now];
    int Mid=(L+R)>>1; ll res=0;
    pushdown(Now);
    if(l<=Mid) res+=querysum(Now<<1,L,Mid,l,r);
    if(r>Mid) res+=querysum(Now<<1|1,Mid+1,R,l,r);
    return res;
}
int querymax(int Now,int L,int R,int l,int r){
    if(l<=L&&r>=R) return mx[Now];
    int Mid=(L+R)>>1,res=-1;
    pushdown(Now);
    if(l<=Mid) res=max(res,querymax(Now<<1,L,Mid,l,r));
    if(r>Mid) res=max(res,querymax(Now<<1|1,Mid+1,R,l,r));
    return res;
}
void update(int Now,int L,int R,int l,int r,int x)
{
    if(mx[Now]<=x) return ;
    if(l<=L&&r>=R){
        if(se[Now]<x){
            sum[Now]-=(ll)mc[Now]*(mx[Now]-x);
            mx[Now]=x;
            return ;
        }
    }
    int Mid=(L+R)>>1;
    pushdown(Now);
    if(l<=Mid) update(Now<<1,L,Mid,l,r,x);
    if(r>Mid) update(Now<<1|1,Mid+1,R,l,r,x);
    pushup(Now);
}
int main()
{
    int T,N,M,L,R,opt,x;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        build(1,1,N);
        while(M--){
            scanf("%d%d%d",&opt,&L,&R);
            if(opt==1) printf("%d\n",querymax(1,1,N,L,R));
            else if(opt==2) printf("%lld\n",querysum(1,1,N,L,R));
            else {
                scanf("%d",&x);
                update(1,1,N,L,R,x);
            }
        }
    }
    return 0;
}

 

相关文章: