zoukankan      html  css  js  c++  java
  • 线段树+单调栈+前缀和--2019icpc南昌网络赛I

    线段树+单调栈+前缀和--2019icpc南昌网络赛I

    Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.

    Now she is planning to find the max value of the intervals in her array. Can you help her?

    Input

    First line contains an integer n(1 le n le 5 imes 10 ^5n(1≤n≤5×105).

    Second line contains nn integers represent the array a (-10^5 le a_i le 10^5)a(−105≤a**i≤105).

    Output

    One line contains an integer represent the answer of the array.

    样例输入复制

    5
    1 2 3 4 5
    

    样例输出复制

    36
    

    思路

    算前缀和,以每个a_i为最低点,用单调栈求出a_i的所能影响的范围

    若a_i>=0,则maxR-minL

    若a_i<0,则minR-min(0,maxL)

    minR,和maxL用线段树查询,线段树构建:以前缀和为底,找出范围内的最值

    代码

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <sstream>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <queue>
    #include <iomanip>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int N = 5e5+5;
    const int MOD = 1e9 + 9;
    const double pi = 3.1415926;
    
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define F(i, l, r) for(int i = l;i <= (r);++i)
    #define RF(i, l, r) for(int i = l;i >= (r);--i)
    
    LL a[N], sum[N], tree_min[N << 2], tree_max[N << 2];
    void build(int l, int r, int rt)
    {
    
        if(l == r)
        {
            tree_min[rt] = tree_max[rt] = sum[l];
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        tree_max[rt] = max(tree_max[rt << 1], tree_max[rt << 1 | 1]);
        tree_min[rt] = min(tree_min[rt << 1], tree_min[rt << 1 | 1]);
    }
    
    LL Query_max(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R)
            return tree_max[rt];
        int m = (l + r) >> 1;
        LL ans = -1e18;
        if(L <= m)
            ans = max(ans, Query_max(L, R, lson));
        if(R > m)
            ans = max(ans, Query_max(L, R, rson));
        return ans;
    }
    
    LL Query_min(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R)
            return tree_min[rt];
        int m = (l + r) >> 1;
        LL ans = INF;
        if(L <= m)
            ans = min(ans, Query_min(L, R, lson));
        if(R > m)
            ans = min(ans, Query_min(L, R, rson));
        return ans;
    }
    
    stack<int> s;
    LL rig[N], lef[N];
    int main()
    {
        int n;
        cin >> n;
        F(i, 1, n)
        {
            cin >> a[i];
            sum[i] = sum[i - 1] + a[i];
        }
        build(1, n, 1);
        F(i, 1, n)
        {
            while(!s.empty() && a[s.top()] > a[i]) {rig[s.top()] = i - 1;s.pop();}
            s.push(i);
        }
        while(!s.empty())
        {
            rig[s.top()] = n;
            s.pop();
        }
        RF(i, n, 1)
        {
            while(!s.empty() && a[s.top()] > a[i]) {lef[s.top()] = i + 1;s.pop();}
            s.push(i);
        }
        while(!s.empty())
        {
            lef[s.top()] = 1;
            s.pop();
        }
        LL ans = -1e18, t;
        F(i, 1, n)
        {
            if(a[i] > 0)
                t = sum[rig[i]] - sum[lef[i] - 1];
            else
                t = Query_min(i, rig[i], 1, n, 1) - max(0ll, Query_max(lef[i], i, 1, n, 1));
            //cout << Query_min(i, rig[i], 1, n, 1) << " " << max(0ll, Query_max(lef[i], i, 1, n, 1)) << endl;
            ans = max(ans, t * a[i]);
        }
        cout << ans << endl;
        return 0;
    }
    
    
  • 相关阅读:
    Android随笔使用ViewPager实现简单地图片的左右滑动切换
    简单地Android中图片的三级缓存机制
    Java中怎么遍历map中value值 (转载)
    创建可执行的jar包
    写出优秀的java代码(转载)
    [JS脚本]ajax status 错误定义
    jsonlib 之jsonConfig详细使用(转载写的不错)
    Driver not found Error when sonar server is just not running
    使用Maven生成manifest
    ECMAScript 面向对象技术
  • 原文地址:https://www.cnblogs.com/shuizhidao/p/10780756.html
Copyright © 2011-2022 走看看