• HDU 5306 Gorgeous Sequence


    如果维护max,sum,那么可以得到一个暴力方法,如果t>=max,那可以return,否则往下更新,显然超时。

    在上面基础上,再维护一下次大值,与最大值的个数。这样一来,次大值<t<最大值 这样的情况也可以更新完了之后直接return,pushDown的话也很好操作。

    实践证明,这样的复杂度降到了nlog(n),具体证明可以看吉如一论文。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
       freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar();  }
    }
    
    const int maxn=1000010;
    struct Seg
    {
        LL sum; int a,b,num;
        bool flag;
    }s[4*maxn];
    int T,n,m;
    
    int M(int a,int b)
    {
        if(a>b) return a;
        return b;
    }
    
    int CI(int x,int a,int b,int c,int d)
    {
        if(a==b&&a==c&&a==d) return x;
        int res=0;
        if(a!=x) res=M(res,a);
        if(b!=x) res=M(res,b);
        if(c!=x) res=M(res,c);
        if(d!=x) res=M(res,d);
        return res;
    }
    
    void pushUp(int rt)
    {
        s[rt].sum=s[2*rt].sum+s[2*rt+1].sum;
        s[rt].a=M(s[2*rt].a,s[2*rt+1].a);
        s[rt].b=CI(s[rt].a,s[2*rt].a,s[2*rt].b,s[2*rt+1].a,s[2*rt+1].b);
        s[rt].num=0;
        if(s[2*rt].a==s[rt].a) s[rt].num=s[rt].num+s[2*rt].num;
        if(s[2*rt+1].a==s[rt].a) s[rt].num=s[rt].num+s[2*rt+1].num;
    }
    
    void pushDown(int rt)
    {
        if(s[rt].flag==0) return;
        int MAX=M(s[2*rt].a,s[2*rt+1].a);
        int t=s[rt].a;
        if(s[2*rt].a==MAX)
        {
            s[2*rt].flag=1;
            s[2*rt].sum=s[2*rt].sum-(LL)(s[2*rt].a-t)*s[2*rt].num;
            if(s[2*rt].a==s[2*rt].b) s[2*rt].a=s[2*rt].b=t;
            else s[2*rt].a=t;
        }
    
        if(s[2*rt+1].a==MAX)
        {
            s[2*rt+1].flag=1;
            s[2*rt+1].sum=s[2*rt+1].sum-(LL)(s[2*rt+1].a-t)*s[2*rt+1].num;
            if(s[2*rt+1].a==s[2*rt+1].b) s[2*rt+1].a=s[2*rt+1].b=t;
            else s[2*rt+1].a=t;
        }
        s[rt].flag=0;
    }
    
    void build(int l,int r,int rt)
    {
        s[rt].num=s[rt].a=s[rt].b=s[rt].sum=0;
        s[rt].flag=0;
        if(l==r)
        {
            scanf("%d",&s[rt].a);
            s[rt].b=s[rt].a;
            s[rt].sum=(LL)s[rt].b;
            s[rt].num=1;
            return;
        }
        int m=(l+r)/2;
        build(l,m,2*rt);
        build(m+1,r,2*rt+1);
        pushUp(rt);
    }
    
    int f(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R) return s[rt].a;
        int m=(l+r)/2;
        int x1=0,x2=0;
        pushDown(rt);
        if(L<=m) x1=f(L,R,l,m,2*rt);
        if(R>m) x2=f(L,R,m+1,r,2*rt+1);
        pushUp(rt);
        return max(x1,x2);
    }
    
    LL sum(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R) return s[rt].sum;
        int m=(l+r)/2;
        LL x1=0,x2=0;
    
        pushDown(rt);
        if(L<=m) x1=sum(L,R,l,m,2*rt);
        if(R>m) x2=sum(L,R,m+1,r,2*rt+1);
        pushUp(rt);
    
        return x1+x2;
    
    }
    
    void force(int t,int l,int r,int rt)
    {
        if(s[rt].a<=t) return;
    
        if(l==r)
        {
            s[rt].a=s[rt].b=s[rt].sum=t;
            return ;
        }
    
        if(s[rt].b<t)
        {
            s[rt].flag=1;
            s[rt].sum=s[rt].sum-(LL)(s[rt].a-t)*s[rt].num;
            s[rt].a=t;
            return;
        }
    
        if(s[rt].b==s[rt].a)
        {
            s[rt].flag=1;
            s[rt].sum=s[rt].sum-(LL)(s[rt].a-t)*s[rt].num;
            s[rt].b=s[rt].a=t;
            return;
        }
    
        pushDown(rt);
        int m=(l+r)/2,tag=0;
        if(s[2*rt].a>t) force(t,l,m,2*rt),tag=1;
        if(s[2*rt+1].a>t) force(t,m+1,r,2*rt+1),tag=1;
        if(tag==1) pushUp(rt);
    }
    
    void update(int L,int R,int t,int l,int r,int rt)
    {
        if(s[rt].a<=t) return;
    
        if(L<=l&&r<=R)
        {
            force(t,l,r,rt);
            return ;
        }
        pushDown(rt);
        int m=(l+r)/2,tag=0;
        if(L<=m&&s[2*rt].a>t) update(L,R,t,l,m,2*rt),tag=1;
        if(R>m&&s[2*rt+1].a>t) update(L,R,t,m+1,r,2*rt+1),tag=1;
        if(tag==1) pushUp(rt);
    }
    
    int main()
    {
        scanf("%d",&T); while(T--)
        {
            scanf("%d%d",&n,&m);
            build(1,n,1);
            for(int i=1;i<=m;i++)
            {
                int op,x,y;
                scanf("%d%d%d",&op,&x,&y);
                if(op==0)
                {
                    int t; read(t);
                    update(x,y,t,1,n,1);
                }
                else if(op==1) printf("%d
    ",f(x,y,1,n,1));
                else printf("%lld
    ",sum(x,y,1,n,1));
            }
        }
        return 0;
    }
  • 相关阅读:
    Swift开发第六篇——操作运算符也可以重载& func 的参数修饰
    Swift开发第五篇——四个知识点(Struct Mutable方法&Tuple&autoclosure&Optional Chain)
    Swift开发第四篇——柯里化
    Swift开发第三篇——Playground
    Swift开发第一篇——异常处理及断言
    在Linux CentOS 6.5 (Final)上安装git-1.9.0
    如何有效地配置基于Spring的应用系统
    关于URL编码的问题
    如何优化pom依赖项?
    启动Tomcat的几种方式
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5774829.html
Copyright © 2020-2023  润新知