zoukankan      html  css  js  c++  java
  • 2019 南昌网络赛 I. Max answer

    这题是poj2796的变形,用线段树来维护每个负数的对应的最小区间和

    #include<iostream>
    #include<stack>
    #include<stdio.h>
    using namespace std;
    #define ls rt<<1
    #define rs rt<<1|1
    #define ll long long
    const int maxn=5e5+100;
    struct node
    {
        int l,r;
        ll sum,minn,maxx;
        node(int l=0,int r=0,ll sum=0,ll minn=0,ll maxx=0)
        {
            this->l=l;
            this->r=r;
            this->sum=sum;
            this->minn=minn;
            this->maxx=maxx;
        }
    }tree[maxn<<2];
    int L[maxn],R[maxn],a[maxn],n;
    ll pre[maxn],ans=-(5e10+10);
    stack<int>sta;
    
    void pushup(int rt)
    {
        tree[rt].sum=tree[ls].sum+tree[rs].sum;
        tree[rt].minn=min(tree[ls].minn,tree[rs].minn);
        tree[rt].maxx=max(tree[ls].maxx,tree[rs].maxx);
    }
    void build(int rt,int l,int r)
    {
        tree[rt].l=l,tree[rt].r=r;
        if(l==r)
        {
            tree[rt].sum=tree[rt].minn=tree[rt].maxx=pre[l];
            return ;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(rt);
    }
    ll queryminn(int rt,int l,int r)
    {
        if(tree[rt].l>=l&&tree[rt].r<=r)
            return tree[rt].minn;
        int mid=(tree[rt].l+tree[rt].r)>>1;
        if(r<=mid)
            return queryminn(ls,l,r);
        else
            if(l>mid)
                return queryminn(rs,l,r);
            else
                return min(queryminn(ls,l,mid),queryminn(rs,mid+1,r));
    }
    ll querymaxx(int rt,int l,int r)
    {
        if(tree[rt].l>=l&&tree[rt].r<=r)
            return tree[rt].maxx;
        int mid=(tree[rt].l+tree[rt].r)>>1;
        if(r<=mid)
            return querymaxx(ls,l,r);
        else
            if(l>mid)
                return querymaxx(rs,l,r);
            else
                return max(querymaxx(ls,l,mid),querymaxx(rs,mid+1,r));
    }
    int main()
    {
        scanf("%d",&n);
        a[0]=-1e5-10;;
        a[n+1]=-1e5-10;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i];
        build(1,1,n);
        for(int i=1;i<=n+1;i++)
        {
            if(sta.empty()||a[i]>=a[sta.top()])
                sta.push(i);
            else
            {
                while(!sta.empty()&&a[i]<a[sta.top()])
                {
                    R[sta.top()]=i-1;
                    sta.pop();
                }
                sta.push(i);
            }
        }
        sta.pop();
        for(int i=n;i>=0;i--)
        {
            if(sta.empty()||a[i]>=a[sta.top()])
                sta.push(i);
            else
            {
                while(!sta.empty()&&a[i]<a[sta.top()])
                {
                    L[sta.top()]=i+1;
                    sta.pop();
                }
                sta.push(i);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]>=0)
                ans=max(ans,(pre[R[i]]-pre[L[i]-1])*a[i]);
            else
                ans=max(ans,(queryminn(1,i,R[i])-((L[i]==i)?pre[i-1]:querymaxx(1,L[i],i-1)))*a[i]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    JS: Promise
    JS: 数据结构与算法之栈
    JS: 数组乱序
    JS: 数组扁平化
    JS:函数柯里化
    JS: 防抖节流
    JS:事件委托
    理解Node.js(译文)
    Javascript闭包入门(译文)
    你真的懂ajax吗?
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754772.html
Copyright © 2011-2022 走看看