# Maximize sum of array by reducing array elements to contain no triplets (i, j, k) where a[i] < a[j] and a[i] < a[k] and j <i < k

• Difficulty Level : Expert
• Last Updated : 30 Jul, 2021

Given an array arr[] consisting of N integers, the task is to find the maximum sum of an array formed by decreasing array elements by 1 any number of times(possibly zero) such that there are no triplets (i, j, k)( 1-based indexing ) such that arr[j] > arr[i] and arr[k] > arr[i], where 1 â‰¤ j < i < k â‰¤ N. Print the resultant array also after performing the decrement operation.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr[] = {1, 2, 1, 2, 1, 3, 1}
Output:
Sum = 9
Final Array = {1, 1, 1, 1, 1, 3, 1}

Input: arr[] = {2, 4, 1, 2, 3, 1, 2}
Output
Sum = 11
Final Array: {2, 4, 1, 1, 1, 1, 1}

Naive Approach: The idea is to update the array either increasing or decreasing or first increasing and then decreasing to get the maximum sum of all the array elements after the update. Follow the below steps to solve the problem:

1. Traverse the given array in the range [0, N – 1].
2. For each index j update arr[j] as min(arr[j], b[j+1]), where b[] is storing temporary array which follow the required conditions and 0 <= j < i.
3. For each index j update arr[j] as min(arr[j], b[j-1]), where i + 1 <= j < N.
4. Calculate the maximum sum from each generated b[].
5. Print the array b[] having the maximum sum.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to find and print maximum``// sum and corresponding array``void` `maximumSum(``int` `m[], ``int` `n)``{``    ``int` `cnt = 0, ans = 0;` `    ``// b stores temporary array when``    ``// element at index i is peak``    ``// c stores final array``    ``vector<``int``> b(n), c(n);` `    ``// Check the array for each index``    ``for` `(``int` `i = 0; i < n; i++) {` `        ``// Choose m[i] as peak``        ``b[i] = m[i];``        ``cnt = b[i];` `        ``// Check left``        ``for` `(``int` `j = i - 1; j >= 0; j--) {``            ``b[j] = min(b[j + 1], m[j]);``            ``cnt += b[j];``        ``}` `        ``// Check right``        ``for` `(``int` `j = i + 1; j < n; j++) {``            ``b[j] = min(b[j - 1], m[j]);``            ``cnt += b[j];``        ``}` `        ``// Check if sum is maximum``        ``if` `(ans < cnt) {``            ``ans = cnt;` `            ``// Store the current array``            ``for` `(``int` `j = 0; j < n; j++) {``                ``c[j] = b[j];``            ``}``        ``}``    ``}` `    ``// Calculate sum``    ``int` `sum = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``sum += c[i];``    ``}``    ``cout << ``"Sum = "` `<< sum << endl;` `    ``// Print array``    ``cout << ``"Final Array = "``;``    ``for` `(``int` `i = 0; i < n; i++) {``        ``cout << c[i] << ``" "``;``    ``}``}` `// Drive Code``int` `main()``{``    ``// Given array``    ``int` `arr[] = { 1, 2, 1, 2, 1, 3, 1 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Function Call``    ``maximumSum(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for``// the above approach``import` `java.util.*;``class` `GFG{` `// Function to find and print maximum``// sum and corresponding array``static` `void` `maximumSum(``int` `m[], ``int` `n)``{``  ``int` `cnt = ``0``, ans = ``0``;` `  ``// b stores temporary array when``  ``// element at index i is peak``  ``// c stores final array``  ``int` `[]b = ``new` `int``[n];``  ``int` `[]c = ``new` `int``[n];` `  ``// Check the array for each index``  ``for` `(``int` `i = ``0``; i < n; i++)``  ``{``    ``// Choose m[i] as peak``    ``b[i] = m[i];``    ``cnt = b[i];` `    ``// Check left``    ``for` `(``int` `j = i - ``1``; j >= ``0``; j--)``    ``{``      ``b[j] = Math.min(b[j + ``1``], m[j]);``      ``cnt += b[j];``    ``}` `    ``// Check right``    ``for` `(``int` `j = i + ``1``; j < n; j++)``    ``{``      ``b[j] = Math.min(b[j - ``1``], m[j]);``      ``cnt += b[j];``    ``}` `    ``// Check if sum is maximum``    ``if` `(ans < cnt)``    ``{``      ``ans = cnt;` `      ``// Store the current array``      ``for` `(``int` `j = ``0``; j < n; j++)``      ``{``        ``c[j] = b[j];``      ``}``    ``}``  ``}` `  ``// Calculate sum``  ``int` `sum = ``0``;` `  ``for` `(``int` `i = ``0``; i < n; i++)``  ``{``    ``sum += c[i];``  ``}``  ``System.out.print(``"Sum = "` `+ ``                    ``sum + ``"\n"``);` `  ``// Print array``  ``System.out.print(``"Final Array = "``);``  ``for` `(``int` `i = ``0``; i < n; i++)``  ``{``    ``System.out.print(c[i] + ``" "``);``  ``}``}` `// Drive Code``public` `static` `void` `main(String[] args)``{``  ``// Given array``  ``int` `arr[] = {``1``, ``2``, ``1``, ``2``, ``1``, ``3``, ``1``};` `  ``int` `N = arr.length;` `  ``// Function Call``  ``maximumSum(arr, N);``}``}` `// This code is contributed by Princi Singh`

## Python3

 `# Python3 program for the above approach` `# Function to find and print maximum``# sum and corresponding array``def` `maximumSum(m, n):``    ` `    ``cnt ``=` `0``    ``ans ``=` `0``    ` `    ``# b stores temporary array when``    ``# element at index i is peak``    ``# c stores final array``    ``b ``=` `[``0` `for` `i ``in` `range``(n)]``    ``c ``=` `[``0` `for` `i ``in` `range``(n)]``    ` `    ``# Check the array for each index``    ``for` `i ``in` `range``(n):``        ` `        ``# Choose m[i] as peak``        ``b[i] ``=` `m[i]``        ``cnt ``=` `b[i]``        ` `        ``# Check left``        ``for` `j ``in` `range``(i ``-` `1``, ``-``1``, ``-``1``):``            ``b[j] ``=` `min``(b[j ``+` `1``], m[j])``            ``cnt ``+``=` `b[j]``        ` `        ``# Check right``        ``for` `j ``in` `range``(i ``+` `1``, n):``            ``b[j] ``=` `min``(b[j ``-` `1``], m[j])``            ``cnt ``+``=` `b[j]``        ` `        ``# Check if sum is maximum``        ``if` `(ans < cnt):``            ``ans ``=` `cnt``            ` `            ``# Store the current array``            ``for` `j ``in` `range``(n):``                ``c[j] ``=` `b[j]``    ` `    ``# Calculate sum and printing``    ``print``(``"Sum = "``, ``sum``(c))``    ``print``(``"Final Array = "``, ``*``c)``    ` `# Driver Code``arr ``=` `[ ``1``, ``2``, ``1``, ``2``, ``1``, ``3``, ``1` `]` `N ``=` `len``(arr) ``/``/` `arr[``0``]` `# Function call``maximumSum(arr, N)` `# This code is contributed by dadi madhav`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `// Function to find and print maximum``// sum and corresponding array``static` `void` `maximumSum(``int` `[]m, ``int` `n)``{``    ``int` `cnt = 0, ans = 0;``    ` `    ``// b stores temporary array when``    ``// element at index i is peak``    ``// c stores readonly array``    ``int` `[]b = ``new` `int``[n];``    ``int` `[]c = ``new` `int``[n];``    ` `    ``// Check the array for each index``    ``for``(``int` `i = 0; i < n; i++)``    ``{``        ` `        ``// Choose m[i] as peak``        ``b[i] = m[i];``        ``cnt = b[i];``        ` `        ``// Check left``        ``for``(``int` `j = i - 1; j >= 0; j--)``        ``{``            ``b[j] = Math.Min(b[j + 1], m[j]);``            ``cnt += b[j];``        ``}``        ` `        ``// Check right``        ``for``(``int` `j = i + 1; j < n; j++)``        ``{``            ``b[j] = Math.Min(b[j - 1], m[j]);``            ``cnt += b[j];``        ``}``        ` `        ``// Check if sum is maximum``        ``if` `(ans < cnt)``        ``{``            ``ans = cnt;``            ` `            ``// Store the current array``            ``for``(``int` `j = 0; j < n; j++)``            ``{``                ``c[j] = b[j];``            ``}``        ``}``    ``}``    ` `    ``// Calculate sum``    ``int` `sum = 0;``    ` `    ``for``(``int` `i = 0; i < n; i++)``    ``{``        ``sum += c[i];``    ``}``    ``Console.Write(``"Sum = "` `+ ``                   ``sum + ``"\n"``);``    ` `    ``// Print array``    ``Console.Write(``"Final Array = "``);``    ``for``(``int` `i = 0; i < n; i++)``    ``{``        ``Console.Write(c[i] + ``" "``);``    ``}``}` `// Drive Code``public` `static` `void` `Main(String[] args)``{``    ` `    ``// Given array``    ``int` `[]arr = { 1, 2, 1, 2, 1, 3, 1 };``    ` `    ``int` `N = arr.Length;``    ` `    ``// Function call``    ``maximumSum(arr, N);``}``}` `// This code is contributed by Amit Katiyar`

## Javascript

 ``
Output:
```Sum = 9
Final Array = 1 1 1 1 1 3 1```

Time Complexity: O(N2), where N is the size of the given array.
Auxiliary Space: O(N)

Efficient Approach: The idea is to use a Segment Tree to solve this problem efficiently. Follow the below steps to solve the above problem:

• Create a Segment Tree which returns the index of the smallest element in the range [l, r].
• Search for the smallest element in [l, r]. Suppose it is at minindex.
• Then make 2 recursive calls:
• Assuming that all arr[l….minindex] have been changed to arr[minindex]. Therefore, the sum of all values is given by:

arr[minindex]*(minindex – l+1)

• Then make the recursive call on [minindex + 1, r] and change all arr[minindex + 1, r] to arr[minindex]. Therefore, the sum of all values is given by:

arr[minindex]*(r – minindex + 1)

• In the base case, if l==r, then it is the final sum of the array when l or r is peak.
• Then simply find the optimal peak, i.e. the one with maximum value.
• After finding the optimal peak, print the array and its sum.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;``int` `peak, maxi = -1;` `// For storing segment tree``int` `seg[4 * 500001];` `// Initialize segment tree``void` `built(``int` `l, ``int` `r, ``int` `index,``        ``int` `a[])``{``    ``// Base Case``    ``if` `(l == r) {``        ``seg[index] = l;``        ``return``;``    ``}` `    ``// Get mid``    ``int` `m = l + (r - l) / 2;` `    ``// Recurr from l to m``    ``built(l, m, 2 * index, a);` `    ``// Recurr from m+1 to r``    ``built(m + 1, r, 2 * index + 1, a);` `    ``if` `(a[seg[2 * index]]``        ``< a[seg[2 * index + 1]])``        ``seg[index] = seg[2 * index];``    ``else``        ``seg[index] = seg[2 * index + 1];``}` `// Query to find minimum value index``// between l and r``int` `query(``int` `l, ``int` `r, ``int` `s, ``int` `e,``        ``int` `index, ``int` `a[])``{``    ``// If segment is invalid``    ``if` `(s > r || e < l)``        ``return` `-1;` `    ``// If segment is inside the``    ``// desired segment``    ``if` `(s >= l && e <= r)``        ``return` `seg[index];` `    ``// Find the mid``    ``int` `m = s + (e - s) / 2;` `    ``// Recurr for the left``    ``int` `d1 = query(l, r, s, m,``                ``2 * index, a);` `    ``// Recurr for the right``    ``int` `d2 = query(l, r, m + 1, e,``                ``2 * index + 1, a);` `    ``// Update the query``    ``if` `(d1 == -1)``        ``return` `d2;``    ``if` `(d2 == -1)``        ``return` `d1;``    ``if` `(a[d1] < a[d2])``        ``return` `d1;``    ``else``        ``return` `d2;``}` `// Function for finding the optimal peak``void` `optimalPeak(``int` `l, ``int` `r, ``int` `value,``                ``int` `n, ``int` `a[])``{``    ``if` `(l > r)``        ``return``;` `    ``// Check if its the peak``    ``if` `(l == r) {` `        ``// Update the value for the``        ``// maximum sum``        ``if` `(value + a[l] > maxi) {``            ``maxi = a[l] + value;``            ``peak = l;``            ``return``;``        ``}``        ``return``;``    ``}` `    ``// Index of minimum element in``    ``// l and r``    ``int` `indexmini = query(l, r, 0,``                        ``n - 1, 1, a);` `    ``int` `value1 = a[indexmini]``                ``* (indexmini - l + 1);` `    ``// Recurr right of minimum index``    ``optimalPeak(indexmini + 1, r,``                ``value + value1, n, a);` `    ``// Update the max and peak value``    ``if` `(indexmini + 1 > r) {``        ``if` `(value + value1 > maxi) {``            ``maxi = value + value1;``            ``peak = indexmini;``        ``}``    ``}` `    ``int` `value2 = a[indexmini]``                ``* (r - indexmini + 1);` `    ``// Recurr left of minimum index``    ``optimalPeak(l, indexmini - 1,``                ``value + value2, n, a);` `    ``// Update the max and peak value``    ``if` `(l > indexmini - 1) {``        ``if` `(value + value2 > maxi) {``            ``maxi = value + value2;``            ``peak = l;``        ``}``    ``}``}` `// Print maximum sum and the array``void` `maximumSum(``int` `a[], ``int` `n)``{``    ``// Initialize segment tree``    ``built(0, n - 1, 1, a);` `    ``// Get the peak``    ``optimalPeak(0, n - 1, 0, n, a);` `    ``// Store the required array``    ``int` `ans[n];``    ``ans[peak] = a[peak];` `    ``// Update the ans[]``    ``for` `(``int` `i = peak + 1; i < n; i++) {``        ``ans[i] = min(ans[i - 1], a[i]);``    ``}` `    ``for` `(``int` `i = peak - 1; i >= 0; i--) {``        ``ans[i] = min(a[i], ans[i + 1]);``    ``}` `    ``// Find the maximum sum``    ``int` `sum = 0;``    ``for` `(``int` `i = 0; i < n; i++) {``        ``sum += ans[i];``    ``}` `    ``// Print sum and optimal array``    ``cout << ``"Sum = "``        ``<< sum << endl;` `    ``cout << ``"Final Array = "``;``    ``for` `(``int` `i = 0; i < n; i++) {``        ``cout << ans[i] << ``" "``;``    ``}``}` `// Drive Code``int` `main()``{``    ``// Given array``    ``int` `arr[] = { 1, 2, 1, 2, 1, 3, 1 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Function Call``    ``maximumSum(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach`  `import` `java.util.*;` `class` `GFG{``static` `int` `peak, maxi = -``1``;` `// For storing segment tree``static` `int` `[]seg = ``new` `int``[``4` `* ``500001``];` `// Initialize segment tree``static` `void` `built(``int` `l, ``int` `r, ``int` `index,``        ``int` `a[])``{``    ``// Base Case``    ``if` `(l == r) {``        ``seg[index] = l;``        ``return``;``    ``}` `    ``// Get mid``    ``int` `m = l + (r - l) / ``2``;` `    ``// Recurr from l to m``    ``built(l, m, ``2` `* index, a);` `    ``// Recurr from m+1 to r``    ``built(m + ``1``, r, ``2` `* index + ``1``, a);` `    ``if` `(a[seg[``2` `* index]]``        ``< a[seg[``2` `* index + ``1``]])``        ``seg[index] = seg[``2` `* index];``    ``else``        ``seg[index] = seg[``2` `* index + ``1``];``}` `// Query to find minimum value index``// between l and r``static` `int` `query(``int` `l, ``int` `r, ``int` `s, ``int` `e,``        ``int` `index, ``int` `a[])``{``    ``// If segment is invalid``    ``if` `(s > r || e < l)``        ``return` `-``1``;` `    ``// If segment is inside the``    ``// desired segment``    ``if` `(s >= l && e <= r)``        ``return` `seg[index];` `    ``// Find the mid``    ``int` `m = s + (e - s) / ``2``;` `    ``// Recurr for the left``    ``int` `d1 = query(l, r, s, m,``                ``2` `* index, a);` `    ``// Recurr for the right``    ``int` `d2 = query(l, r, m + ``1``, e,``                ``2` `* index + ``1``, a);` `    ``// Update the query``    ``if` `(d1 == -``1``)``        ``return` `d2;``    ``if` `(d2 == -``1``)``        ``return` `d1;``    ``if` `(a[d1] < a[d2])``        ``return` `d1;``    ``else``        ``return` `d2;``}` `// Function for finding the optimal peak``static` `void` `optimalPeak(``int` `l, ``int` `r, ``int` `value,``                ``int` `n, ``int` `a[])``{``    ``if` `(l > r)``        ``return``;` `    ``// Check if its the peak``    ``if` `(l == r) {` `        ``// Update the value for the``        ``// maximum sum``        ``if` `(value + a[l] > maxi) {``            ``maxi = a[l] + value;``            ``peak = l;``            ``return``;``        ``}``        ``return``;``    ``}` `    ``// Index of minimum element in``    ``// l and r``    ``int` `indexmini = query(l, r, ``0``,``                        ``n - ``1``, ``1``, a);` `    ``int` `value1 = a[indexmini]``                ``* (indexmini - l + ``1``);` `    ``// Recurr right of minimum index``    ``optimalPeak(indexmini + ``1``, r,``                ``value + value1, n, a);` `    ``// Update the max and peak value``    ``if` `(indexmini + ``1` `> r) {``        ``if` `(value + value1 > maxi) {``            ``maxi = value + value1;``            ``peak = indexmini;``        ``}``    ``}` `    ``int` `value2 = a[indexmini]``                ``* (r - indexmini + ``1``);` `    ``// Recurr left of minimum index``    ``optimalPeak(l, indexmini - ``1``,``                ``value + value2, n, a);` `    ``// Update the max and peak value``    ``if` `(l > indexmini - ``1``) {``        ``if` `(value + value2 > maxi) {``            ``maxi = value + value2;``            ``peak = l;``        ``}``    ``}``}` `// Print maximum sum and the array``static` `void` `maximumSum(``int` `a[], ``int` `n)``{``    ``// Initialize segment tree``    ``built(``0``, n - ``1``, ``1``, a);` `    ``// Get the peak``    ``optimalPeak(``0``, n - ``1``, ``0``, n, a);` `    ``// Store the required array``    ``int` `[]ans = ``new` `int``[n];``    ``ans[peak] = a[peak];` `    ``// Update the ans[]``    ``for` `(``int` `i = peak + ``1``; i < n; i++) {``        ``ans[i] = Math.min(ans[i - ``1``], a[i]);``    ``}` `    ``for` `(``int` `i = peak - ``1``; i >= ``0``; i--) {``        ``ans[i] = Math.min(a[i], ans[i + ``1``]);``    ``}` `    ``// Find the maximum sum``    ``int` `sum = ``0``;``    ``for` `(``int` `i = ``0``; i < n; i++) {``        ``sum += ans[i];``    ``}` `    ``// Print sum and optimal array``    ``System.out.print(``"Sum = "``        ``+ sum +``"\n"``);` `    ``System.out.print(``"Final Array = "``);``    ``for` `(``int` `i = ``0``; i < n; i++) {``        ``System.out.print(ans[i]+ ``" "``);``    ``}``}` `// Drive Code``public` `static` `void` `main(String[] args)``{``    ``// Given array``    ``int` `arr[] = { ``1``, ``2``, ``1``, ``2``, ``1``, ``3``, ``1` `};` `    ``int` `N = arr.length;` `    ``// Function Call``    ``maximumSum(arr, N);` `}``}` `// This code contributed by gauravrajput1`

## Python3

 `# Python3 program for the above approach``peak ``=` `0``maxi ``=` `-``1` `# For storing segment tree``seg ``=` `[``0` `for` `i ``in` `range``(``4` `*` `500001``)]` `# Initialize segment tree``def` `built(l, r, index, a):``    ` `    ``# Base Case``    ``if` `(l ``=``=` `r):``        ``seg[index] ``=` `l``        ``return` `    ``# Get mid``    ``m ``=` `int``(l ``+` `(r ``-` `l) ``/` `2``)` `    ``# Recurr from l to m``    ``built(l, m, ``2` `*` `index, a)` `    ``# Recurr from m+1 to r``    ``built(m ``+` `1``, r, ``2` `*` `index ``+` `1``, a)` `    ``if` `(a[seg[``2` `*` `index]] <``        ``a[seg[``2` `*` `index ``+` `1``]]):``        ``seg[index] ``=` `seg[``2` `*` `index]``    ``else``:``        ``seg[index] ``=` `seg[``2` `*` `index ``+` `1``]` `# Query to find minimum value index``# between l and r``def` `query(l, r, s, e, index, a):` `    ``# If segment is invalid``    ``if` `(s > r ``or` `e < l):``        ``return` `-``1` `    ``# If segment is inside the``    ``# desired segment``    ``if` `(s >``=` `l ``and` `e <``=` `r):``        ``return` `seg[index]` `    ``# Find the mid``    ``m ``=` `int``(s ``+` `(e ``-` `s) ``/` `2``)` `    ``# Recurr for the left``    ``d1 ``=` `query(l, r, s, m,``               ``2` `*` `index, a)` `    ``# Recurr for the right``    ``d2 ``=` `query(l, r, m ``+` `1``, e,``             ``2` `*` `index ``+` `1``, a)` `    ``# Update the query``    ``if` `(d1 ``=``=` `-``1``):``        ``return` `d2``    ``if` `(d2 ``=``=` `-``1``):``        ``return` `d1``    ``if` `(a[d1] < a[d2]):``        ``return` `d1``    ``else``:``        ``return` `d2` `# Function for finding the optimal peak``def` `optimalPeak(l, r, value, n, a):``    ` `    ``global` `maxi, peak``    ` `    ``if` `(l > r):``        ``return` `    ``# Check if its the peak``    ``if` `(l ``=``=` `r):``        ` `        ``# Update the value for the``        ``# maximum sum``        ``if` `(value ``+` `a[l] > maxi):``            ``maxi ``=` `a[l] ``+` `value``            ``peak ``=` `l``            ``return``            ` `        ``return` `    ``# Index of minimum element in``    ``# l and r``    ``indexmini ``=` `query(l, r, ``0``, n ``-` `1``, ``1``, a)``    ``value1 ``=` `a[indexmini] ``*` `(indexmini ``-` `l ``+` `1``)``    ` `    ``# Recurr right of minimum index``    ``optimalPeak(indexmini ``+` `1``, r,``                    ``value ``+` `value1, n, a)` `    ``# Update the max and peak value``    ``if` `(indexmini ``+` `1` `> r):``        ``if` `(value ``+` `value1 > maxi):``            ``maxi ``=` `value ``+` `value1``            ``peak ``=` `indexmini` `    ``value2 ``=` `(a[indexmini] ``*``            ``(r ``-` `indexmini ``+` `1``))` `    ``# Recurr left of minimum index``    ``optimalPeak(l, indexmini ``-` `1``,``                ``value ``+` `value2, n, a)` `    ``# Update the max and peak value``    ``if` `(l > indexmini ``-` `1``):``        ``if` `(value ``+` `value2 > maxi):``            ``maxi ``=` `value ``+` `value2``            ``peak ``=` `l` `# Print maximum sum and the array``def` `maximumSum(a, n):` `    ``# Initialize segment tree``    ``built(``0``, n ``-` `1``, ``1``, a)` `    ``# Get the peak``    ``optimalPeak(``0``, n ``-` `1``, ``0``, n, a)` `    ``# Store the required array``    ``ans ``=` `[``0` `for` `i ``in` `range``(n)]` `    ``ans[peak] ``=` `a[peak]` `    ``# Update the ans[]``    ``for` `i ``in` `range``(peak ``+` `1``, n):``        ``ans[i] ``=` `min``(ans[i ``-` `1``], a[i])``    ``for` `i ``in` `range``(peak ``-` `1``, ``-``1``, ``-``1``):``        ``ans[i] ``=` `min``(a[i], ans[i ``+` `1``])` `    ``# Find the maximum sum``    ``Sum` `=` `0``    ``Sum` `=` `sum``(ans)` `    ``# Print sum and optimal array``    ``print``(``"Sum = "``, ``Sum``)` `    ``print``(``"Final Array = "``, end ``=` `"")``    ``print``(``*``ans, sep ``=` `" "``)` `# Driver Code` `# Given array``arr ``=` `[ ``1``, ``2``, ``1``, ``2``, ``1``, ``3``, ``1` `]``N ``=` `len``(arr)` `# Function Call``maximumSum(arr, N)` `# This code is contributed by rag2127`

## C#

 `// C# program for``// the above approach``using` `System;``class` `GFG{` `static` `int` `peak, maxi = -1;` `// For storing segment tree``static` `int` `[]seg = ``new` `int``[4 * 500001];` `// Initialize segment tree``static` `void` `built(``int` `l, ``int` `r,``                ``int` `index, ``int` `[]a)``{``// Base Case``if` `(l == r)``{``    ``seg[index] = l;``    ``return``;``}` `// Get mid``int` `m = l + (r - l) / 2;` `// Recurr from l to m``built(l, m, 2 * index, a);` `// Recurr from m+1 to r``built(m + 1, r, 2 * index + 1, a);` `if` `(a[seg[2 * index]] <``    ``a[seg[2 * index + 1]])``    ``seg[index] = seg[2 * index];``else``    ``seg[index] = seg[2 * index + 1];``}` `// Query to find minimum value index``// between l and r``static` `int` `query(``int` `l, ``int` `r,``                ``int` `s, ``int` `e,``                ``int` `index, ``int` `[]a)``{``// If segment is invalid``if` `(s > r || e < l)``    ``return` `-1;` `// If segment is inside the``// desired segment``if` `(s >= l && e <= r)``    ``return` `seg[index];` `// Find the mid``int` `m = s + (e - s) / 2;` `// Recurr for the left``int` `d1 = query(l, r, s, m,``                ``2 * index, a);` `// Recurr for the right``int` `d2 = query(l, r, m + 1, e,``                ``2 * index + 1, a);` `// Update the query``if` `(d1 == -1)``    ``return` `d2;``if` `(d2 == -1)``    ``return` `d1;``if` `(a[d1] < a[d2])``    ``return` `d1;``else``    ``return` `d2;``}` `// Function for finding the optimal peak``static` `void` `optimalPeak(``int` `l, ``int` `r,``                        ``int` `value, ``int` `n, ``int` `[]a)``{``if` `(l > r)``    ``return``;` `// Check if its the peak``if` `(l == r)``{``    ``// Update the value for the``    ``// maximum sum``    ``if` `(value + a[l] > maxi)``    ``{``    ``maxi = a[l] + value;``    ``peak = l;``    ``return``;``    ``}``    ``return``;``}` `// Index of minimum element in``// l and r``int` `indexmini = query(l, r, 0,``                        ``n - 1, 1, a);` `int` `value1 = a[indexmini] *``                ``(indexmini - l + 1);` `// Recurr right of minimum index``optimalPeak(indexmini + 1, r,``            ``value + value1, n, a);` `// Update the max and peak value``if` `(indexmini + 1 > r)``{``    ``if` `(value + value1 > maxi)``    ``{``    ``maxi = value + value1;``    ``peak = indexmini;``    ``}``}` `int` `value2 = a[indexmini] *``                ``(r - indexmini + 1);` `// Recurr left of minimum index``optimalPeak(l, indexmini - 1,``            ``value + value2, n, a);` `// Update the max and peak value``if` `(l > indexmini - 1)``{``    ``if` `(value + value2 > maxi)``    ``{``    ``maxi = value + value2;``    ``peak = l;``    ``}``}``}` `// Print maximum sum and the array``static` `void` `maximumSum(``int` `[]a, ``int` `n)``{``// Initialize segment tree``built(0, n - 1, 1, a);` `// Get the peak``optimalPeak(0, n - 1, 0, n, a);` `// Store the required array``int` `[]ans = ``new` `int``[n];``ans[peak] = a[peak];` `// Update the ans[]``for` `(``int` `i = peak + 1; i < n; i++)``{``    ``ans[i] = Math.Min(ans[i - 1], a[i]);``}` `for` `(``int` `i = peak - 1; i >= 0; i--)``{``    ``ans[i] = Math.Min(a[i], ans[i + 1]);``}` `// Find the maximum sum``int` `sum = 0;``for` `(``int` `i = 0; i < n; i++)``{``    ``sum += ans[i];``}` `// Print sum and optimal array``Console.Write(``"Sum = "` `+``                ``sum + ``"\n"``);` `Console.Write(``"Final Array = "``);``for` `(``int` `i = 0; i < n; i++)``{``    ``Console.Write(ans[i] + ``" "``);``}``}` `// Drive Code``public` `static` `void` `Main(String[] args)``{``// Given array``int` `[]arr = {1, 2, 1, 2, 1, 3, 1};` `int` `N = arr.Length;` `// Function Call``maximumSum(arr, N);``}``}` `// This code is contributed by shikhasingrajput`

## Javascript

 ``
Output:
```Sum = 9
Final Array = 1 1 1 1 1 3 1```

Time Complexity: O(N*logN), where N is the size of the given array.
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up