zoukankan      html  css  js  c++  java
  • HDU

    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. 

    InputThe 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=100, n1000000, m1000000∑n≤1000000, ∑m≤1000000.
    OutputFor every operation of type 11 or 22, 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
    ",querymax(1,1,N,L,R));
                else if(opt==2) printf("%lld
    ",querysum(1,1,N,L,R));
                else {
                    scanf("%d",&x);
                    update(1,1,N,L,R,x);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    google浏览器高清壁纸保存
    vmworkstation安装unbuntu server 网络配置:NAT模式
    python量化交易相关资料
    Oracle VM VirtualBox启动后莫名奇妙的报错
    oracle RAC 跨网段客户端访问 报ORA-12170
    odoo开发 相关知识点
    C#.ToString()格式大全
    flex简单参考实例
    NPOI读写Excel
    C# Stream 和 byte[] 之间的转换(文件流的应用)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9674828.html
Copyright © 2011-2022 走看看