zoukankan      html  css  js  c++  java
  • 计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛

    Max answer

    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(1n5×105).

    Second line contains nn integers represent the array a (-10^5 le a_i le 10^5)a(105ai105).

    Output

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

    样例输入

    5
    1 2 3 4 5

    样例输出

    36

    用单调栈判断以每个值为最小值的最大左边界和右边界。后对对每个值分成负数和正数讨 论取可行区间内的最小或最大值,方法为求前缀和和后缀和,然后用线段树求区间最值。

    线段树维护的时候,左区间维护后缀和,右区间维护前缀和,找的时候,在i值左边找后缀,在i值右边找前缀,然后交叉的部分就是满足的区间。

    代码:

      1 //I-线段树+单调栈
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn=5e5+10;
      6 const int inf=0x3f3f3f3f;
      7 
      8 #define lson l,m,rt<<1
      9 #define rson m+1,r,rt<<1|1
     10 
     11 int a[maxn],l[maxn],r[maxn];
     12 ll pre[maxn],beh[maxn],maxl[maxn<<2],minl[maxn<<2],maxr[maxn<<2],minr[maxn<<2];
     13 
     14 void pushup(int rt)
     15 {
     16     maxl[rt]=max(maxl[rt<<1],maxl[rt<<1|1]);
     17     minl[rt]=min(minl[rt<<1],minl[rt<<1|1]);
     18     maxr[rt]=max(maxr[rt<<1],maxr[rt<<1|1]);
     19     minr[rt]=min(minr[rt<<1],minr[rt<<1|1]);
     20 }
     21 
     22 void build(int l,int r,int rt)
     23 {
     24     if(l==r){
     25         maxl[rt]=minl[rt]=beh[l];
     26         maxr[rt]=minr[rt]=pre[l];
     27         return ;
     28     }
     29 
     30     int m=(l+r)>>1;
     31     build(lson);
     32     build(rson);
     33     pushup(rt);
     34 }
     35 
     36 ll query(int op,int L,int R,int l,int r,int rt)
     37 {
     38     if(L<=l&&r<=R){
     39         if     (op==1) return maxl[rt];
     40         else if(op==2) return minl[rt];
     41         else if(op==3) return maxr[rt];
     42         else if(op==4) return minr[rt];
     43     }
     44 
     45     int m=(l+r)>>1;
     46     ll ret;
     47     if(op==1||op==3){
     48         ret=-inf;
     49         if(L<=m) ret=max(ret,query(op,L,R,lson));
     50         if(R> m) ret=max(ret,query(op,L,R,rson));
     51     }
     52     else if(op==2||op==4){
     53         ret=inf;
     54         if(L<=m) ret=min(ret,query(op,L,R,lson));
     55         if(R> m) ret=min(ret,query(op,L,R,rson));
     56     }
     57     return ret;
     58 }
     59 
     60 deque<int> deq;//因为是双端队列,所以插的时候要插到头上才能实现栈的功能
     61 
     62 int main()
     63 {
     64     int n;
     65     scanf("%d",&n);
     66     for(int i=1;i<=n;i++){
     67         scanf("%d",&a[i]);
     68     }
     69     for(int i=1;i<=n;i++){
     70         pre[i]=pre[i-1]+a[i];
     71     }
     72     for(int i=n;i>=1;i--){
     73         beh[i]=beh[i+1]+a[i];
     74     }
     75     build(1,n,1);
     76     for(int i=1;i<=n;i++){
     77         while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
     78         if(deq.empty()) l[i]=1;
     79         else l[i]=deq.front()+1;
     80         deq.push_front(i);
     81     }
     82     deq.clear();
     83     for(int i=n;i>=1;i--){
     84         while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
     85         if(deq.empty()) r[i]=n;
     86         else r[i]=deq.front()-1;
     87         deq.push_front(i);
     88     }
     89     ll maxx=-inf,ret;
     90     for(int i=1;i<=n;i++){
     91         if(a[i]>=0){
     92             ret=query(1,l[i],i,1,n,1);
     93             ret+=query(3,i,r[i],1,n,1);
     94             ret=ret-beh[i]-pre[i]+a[i];
     95             ret*=a[i];
     96 //            cout<<query(1,l[i],i,1,n,1)<<" "<<query(3,i,r[i],1,n,1)<<endl;
     97         }
     98         else{
     99             ret=query(2,l[i],i,1,n,1);
    100             ret+=query(4,i,r[i],1,n,1);
    101             ret=ret-beh[i]-pre[i]+a[i];
    102             ret*=a[i];
    103         }
    104         maxx=max(maxx,ret);
    105     }
    106     printf("%lld
    ",maxx);
    107 }
  • 相关阅读:
    IOE是软件时代或是“买计算机”时代的产物;而云计算时代,则是“买计算”的时代。从本质上来说,“去IOE”是一个企业从传统企业向互联网企业转型的标志。
    物联网听起来像是一个和互联网不同的网,"万物互联"又把"网"给弄丢了,正向我们扑面而来的是"万物互联网"。
    移动互联网真正带来的影响,是使人们的大部分时间都消耗在在线社会上了。
    中国剩余定理
    HDU-1013九余数定理
    HDU--1213并查集
    HDU--1232畅通工程
    并查集
    简单的快速幂取模
    线段树
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10821979.html
Copyright © 2011-2022 走看看