Cattle off network training school multi fourth C sequence

(Cattle away games have Cartesian tree, every game will not use Cartesian tree ... autistic, Bu Ti experience)

Topic link: https: //ac.nowcoder.com/acm/contest/884/C

The meaning of problems: given two sequences a, b, find max {min a [l, r] * sum b [l, r]}

A more obvious approach is the best value range by segment tree / ST table maintenance, but nlogn practice often easy to card, (zkw segment tree can be had), but when the race time limit to raise the 3s, well basically wrote

Directly maintain the minimum interval / subscript a large value, and then starts calculating the answer from the minimum, to find the minimum / maximum and the minimum at the left prefix (to find the maximum treatment min a [i] <0), minimum the right side also find a prefix minimum / maximum values ​​and calculated once the answer, then the minimum value as a dividing line, divided into two parts continue to calculate

LogN segment tree query efficiency, overall complexity O (nlogn), ST pretreatment nlogn table, overall complexity is O (nlogn) and large constant, after the game with the immortal found O (n) approach, also studied look, yes, that is the magic of Cartesian tree

We analyze the process of solving the answer, find someone to find is the minimum, and then find the order of small ... times, we build on a Cartesian tree array, then the answer to solving process is the process of tree dfs, since it is dfs of the tree, we can use mn [rt], mx [rt] to rt array to record the root subtree contains Zheke prefix and the prefix and the minimum,

Then the process dfs, can be constantly updated with the subtree, then we O (1) calculate the answer to every single sub-tree, the overall complexity is O (n) of

Cartesian tree:

Constructed by monotonous stack, this process is O (n), and each element x onto the stack, before finding a smaller than his element p, then it is the right son tree Fengyun Descartes element p corresponding node, the original q right son left his son becomes the current insertion element x, the son of former right q is the last element of the stack, the stack if no element, that is, as a Cartesian tree leaf node is inserted, the insertion position is Right son of the top element of the stack when not

Cartesian tree of properties: Properties of element index satisfying binary search tree, an element value satisfies properties stack

Cartesian root node is a monotonically bottom of the stack the stack elements, but also the minimum value of the entire sequence, every single root subtree is within a minimum range, the LCA tree two elements may be used to solve the problem RMQ

#include <bits / STDC ++ H.>
 the using  namespace STD;
 the using LL = Long  Long ;
 const  int N = 3E6 + . 5 ;
 int A [N]; 
LL B [N]; 
int Son [N] [ 2 ], n-; / / 0 1 left and right son son 
int STA [N]; 
LL Mn [N], MX [N]; // record the current subtree smallest and largest prefix 
LL ANS = - 3E18;
 void DFS ( int RT, int L, int R & lt) 
{ 
    IF (Son [RT] [ 0 ]) DFS (Son [RT] [ 0 ], L, RT- . 1);
     IF (Son [RT] [ . 1 ]) DFS (Son [RT] [ . 1 ], + RT . 1 , R & lt);
     // left subtree l-1 does not include this point, however, we want to take into account this prefix and otherwise, little is calculated to b [l], not a right subtree including the root node, b [rt] should be taken into account 
    LL minL = min (Mn [son [RT] [ 0 ]], B [L- . 1 ]) ; 
    LL MaxL = max (MX [Son [RT] [ 0 ]], B [L- . 1 ]); 
    LL MINR = min (Mn [Son [RT] [ . 1 ]], B [RT]); 
    LL MAXR = max (MX [Son [RT] [ . 1 ]], B [RT]); 
    ANS = max (ANS, A [RT] * (maxr- minL)); 
    ANS = max (ANS, A [RT] * (MINR - MaxL));
     //The write current is also taken into account the sub-root 
    Mn [RT] = min (minL, MINR); 
    MX [RT] = max (MaxL, MAXR); 
} 
int main () 
{ 
    int n-; 
    iOS :: sync_with_stdio ( to false ); 
    cin.tie ( 0 ); 
    cout.tie ( 0 ); 
    CIN >> n-;
     int Top = 0 ;
     for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        CIN >> A [I];
         the while (Top && A [I] <A [STA [Top]]) Son [I] [ 0 ] = STA [top--];
        if(top)son[sta[top]][1]=i;
        sta[++top]=i;
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
        b[i]+=b[i-1];
    }
    mn[0]=3e18;mx[0]=-3e18;
    dfs(sta[1],1,n);
    cout<<ans<<endl;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/xusirui/p/11257553.html