Banana-Leopard/TASTY huggingface dataset:
// C++ program to find smallest and
// second smallest elements
#include <bits/stdc++.h>
using namespace std; /* For INT_MAX */
 
void print2Smallest(int arr[], int arr_size)
{
    int i, first, second;
 
    /* There should be atleast two elements */
    if (arr_size < 2)
    {
        cout<<" Invalid Input ";
        return;
    }
 
    first = second = INT_MAX;
    for (i = 0; i < arr_size ; i ++)
    {
        /* If current element is smaller than first
        then update both first and second */
        if (arr[i] < first)
        {
            second = first;
            first = arr[i];
        }
 
        /* If arr[i] is in between first and second
        then update second */
        else if (arr[i] < second && arr[i] != first)
            second = arr[i];
    }
    if (second == INT_MAX)
        cout << "There is no second smallest element\n";
    else
        cout << "The smallest element is " << first << " and second "
            "Smallest element is " << second << endl;
}
 
/* Driver code */
int main()
{
    int arr[] = {12, 13, 1, 10, 34, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
    print2Smallest(arr, n);
    return 0;
}
 
// This is code is contributed by rathbhupendra

Time complexity: linear
Space complexity: constant
// C++ program to find the smallest elements
// missing in a sorted array.
#include<bits/stdc++.h>
using namespace std;
 
int findFirstMissing(int array[],
                    int start, int end)
{
    if (start > end)
        return end + 1;
 
    if (start != array[start])
        return start;
 
    int mid = (start + end) / 2;
 
    // Left half has all elements
    // from 0 to mid
    if (array[mid] == mid)
        return findFirstMissing(array,
                            mid+1, end);
 
    return findFirstMissing(array, start, mid);
}
 
// Driver code
int main()
{
    int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Smallest missing element is " <<
        findFirstMissing(arr, 0, n-1) << endl;
}
 
// This code is contributed by
// Shivi_Aggarwal

Time complexity: logn
Space complexity: logn
//C++ program for the above approach
#include <bits/stdc++.h>
 
using namespace std;
 
// Program to find missing element
int findFirstMissing(vector<int> arr , int start ,
                        int  end,int first)
{
 
  if (start < end)
  {
    int mid = (start + end) / 2;
 
    /** Index matches with value
      at that index, means missing
      element cannot be upto that po*/
    if (arr[mid] != mid+first)
      return findFirstMissing(arr, start,
                                 mid , first);
    else
      return findFirstMissing(arr, mid + 1,
                                 end , first);
  }
  return start + first;
 
}
 
// Program to find Smallest
// Missing in Sorted Array
int findSmallestMissinginSortedArray(vector<int> arr)
{
   
  // Check if 0 is missing
  // in the array
  if(arr[0] != 0)
    return 0;
 
  // Check is all numbers 0 to n - 1
  // are present in array
  if(arr[arr.size() - 1] == arr.size() - 1)
    return arr.size();
 
  int first = arr[0];
 
  return findFirstMissing(arr, 0, arr.size() - 1, first);
}
 
 
// Driver program to test the above function
int main()
{
    vector<int> arr = {0, 1, 2, 3, 4, 5, 7};
    int n = arr.size();
 
    // Function Call
    cout<<"First Missing element is : "<<findSmallestMissinginSortedArray(arr);
}
 
// This code is contributed by mohit kumar 29.

Time complexity: logn
Space complexity: logn
// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum sum
int findMaxSum(vector<int> arr, int N)
{
    // Declare dp array
    int dp[N][2];
    if (N == 1) {
        return arr[0];
    }
   
    // Initialize the values in dp array
    dp[0][0] = 0;
    dp[0][1] = arr[0];
   
    // Loop to find the maximum possible sum
    for (int i = 1; i < N; i++) {
        dp[i][1] = dp[i - 1][0] + arr[i];
        dp[i][0] = max(dp[i - 1][1],
                       dp[i - 1][0]);
    }
   
    // Return the maximum sum
    return max(dp[N - 1][0], dp[N - 1][1]);
}
 
// Driver Code
int main()
{
    // Creating the array
    vector<int> arr = { 5, 5, 10, 100, 10, 5 };
    int N = arr.size();
 
    // Function call
    cout << findMaxSum(arr, N) << endl;
    return 0;
}

Time complexity: linear
Space complexity: linear
// C++ code to implement the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return max sum such that
// no two elements are adjacent
int FindMaxSum(vector<int> arr, int n)
{
    int incl = arr[0];
    int excl = 0;
    int excl_new;
    int i;
 
    for (i = 1; i < n; i++) {
        // Current max excluding i
        excl_new = max(incl, excl);
 
        // Current max including i
        incl = excl + arr[i];
        excl = excl_new;
    }
 
    // Return max of incl and excl
    return max(incl, excl);
}
 
// Driver code
int main()
{
    vector<int> arr = { 5, 5, 10, 100, 10, 5 };
    int N = arr.size();
 
    // Function call
    cout << FindMaxSum(arr, N);
    return 0;
}
// This approach is contributed by Debanjan

Time complexity: linear
Space complexity: constant
// C++ program to demonstrate working of Square Root
// Decomposition.
#include "iostream"
#include "math.h"
using namespace std;
 
#define MAXN 10000
#define SQRSIZE  100
 
int arr[MAXN];               // original array
int block[SQRSIZE];          // decomposed array
int blk_sz;                      // block size
 
// Time Complexity : O(1)
void update(int idx, int val)
{
    int blockNumber = idx / blk_sz;
    block[blockNumber] += val - arr[idx];
    arr[idx] = val;
}
 
// Time Complexity : O(sqrt(n))
int query(int l, int r)
{
    int sum = 0;
    while (l<r and l%blk_sz!=0 and l!=0)
    {
        // traversing first block in range
        sum += arr[l];
        l++;
    }
    while (l+blk_sz-1 <= r)
    {
        // traversing completely overlapped blocks in range
        sum += block[l/blk_sz];
        l += blk_sz;
    }
    while (l<=r)
    {
        // traversing last block in range
        sum += arr[l];
        l++;
    }
    return sum;
}
 
// Fills values in input[]
void preprocess(int input[], int n)
{
    // initiating block pointer
    int blk_idx = -1;
 
    // calculating size of block
    blk_sz = sqrt(n);
 
    // building the decomposed array
    for (int i=0; i<n; i++)
    {
        arr[i] = input[i];
        if (i%blk_sz == 0)
        {
            // entering next block
            // incrementing block pointer
            blk_idx++;
        }
        block[blk_idx] += arr[i];
    }
}
 
// Driver code
int main()
{
    // We have used separate array for input because
    // the purpose of this code is to explain SQRT
    // decomposition in competitive programming where
    // we have multiple inputs.
    int input[] = {1, 5, 2, 4, 6, 1, 3, 5, 7, 10};
    int n = sizeof(input)/sizeof(input[0]);
 
    preprocess(input, n);
 
    cout << "query(3,8) : " << query(3, 8) << endl;
    cout << "query(1,6) : " << query(1, 6) << endl;
    update(8, 0);
    cout << "query(8,8) : " << query(8, 8) << endl;
    return 0;
}

Time complexity: linear
Space complexity: linear
// C++ program to do range minimum query
// using sparse table
#include <bits/stdc++.h>
using namespace std;
#define MAX 500
 
// lookup[i][j] is going to store minimum
// value in arr[i..j]. Ideally lookup table
// size should not be fixed and should be
// determined using n Log n. It is kept
// constant to keep code simple.
int lookup[MAX][MAX];
 
// Fills lookup array lookup[][] in bottom up manner.
void buildSparseTable(int arr[], int n)
{
    // Initialize M for the intervals with length 1
    for (int i = 0; i < n; i++)
        lookup[i][0] = arr[i];
 
    // Compute values from smaller to bigger intervals
    for (int j = 1; (1 << j) <= n; j++) {
 
        // Compute minimum value for all intervals with
        // size 2^j
        for (int i = 0; (i + (1 << j) - 1) < n; i++) {
 
            // For arr[2][10], we compare arr[lookup[0][7]]
            // and arr[lookup[3][10]]
            if (lookup[i][j - 1] <
                        lookup[i + (1 << (j - 1))][j - 1])
                lookup[i][j] = lookup[i][j - 1];
            else
                lookup[i][j] =
                         lookup[i + (1 << (j - 1))][j - 1];
        }
    }
}
 
// Returns minimum of arr[L..R]
int query(int L, int R)
{
    // Find highest power of 2 that is smaller
    // than or equal to count of elements in given
    // range. For [2, 10], j = 3
    int j = (int)log2(R - L + 1);
 
    // Compute minimum of last 2^j elements with first
    // 2^j elements in range.
    // For [2, 10], we compare arr[lookup[0][3]] and
    // arr[lookup[3][3]],
    if (lookup[L][j] <= lookup[R - (1 << j) + 1][j])
        return lookup[L][j];
 
    else
        return lookup[R - (1 << j) + 1][j];
}
 
// Driver program
int main()
{
    int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };
    int n = sizeof(a) / sizeof(a[0]);
    buildSparseTable(a, n);
    cout << query(0, 4) << endl;
    cout << query(4, 7) << endl;
    cout << query(7, 8) << endl;
    return 0;
}

Time complexity: nlogn
Space complexity: nlogn
// C++ program to do range minimum query
// using sparse table
#include <bits/stdc++.h>
using namespace std;
#define MAX 500
 
// lookup[i][j] is going to store GCD of
// arr[i..j]. Ideally lookup table
// size should not be fixed and should be
// determined using n Log n. It is kept
// constant to keep code simple.
int table[MAX][MAX];
 
// it builds sparse table.
void buildSparseTable(int arr[], int n)
{
    // GCD of single element is element itself
    for (int i = 0; i < n; i++)
        table[i][0] = arr[i];
 
    // Build sparse table
    for (int j = 1; j <= log2(n); j++)
        for (int i = 0; i <= n - (1 << j); i++)
            table[i][j] = __gcd(table[i][j - 1],
                    table[i + (1 << (j - 1))][j - 1]);
}
 
// Returns GCD of arr[L..R]
int query(int L, int R)
{
    // Find highest power of 2 that is smaller
    // than or equal to count of elements in given
    // range.For [2, 10], j = 3
    int j = (int)log2(R - L + 1);
 
    // Compute GCD of last 2^j elements with first
    // 2^j elements in range.
    // For [2, 10], we find GCD of arr[lookup[0][3]] and
    // arr[lookup[3][3]],
    return __gcd(table[L][j], table[R - (1 << j) + 1][j]);
}
 
// Driver program
int main()
{
    int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };
    int n = sizeof(a) / sizeof(a[0]);
    buildSparseTable(a, n);
    cout << query(0, 2) << endl;
    cout << query(1, 3) << endl;
    cout << query(4, 5) << endl;
    return 0;
}

Time complexity: nlogn
Space complexity: nlogn
// C++ program to find total count of an element
// in a range
#include<bits/stdc++.h>
using namespace std;
 
// Returns count of element in arr[left-1..right-1]
int findFrequency(int arr[], int n, int left,
                         int right, int element)
{
    int count = 0;
    for (int i=left-1; i<=right; ++i)
        if (arr[i] == element)
            ++count;
    return count;
}
 
// Driver Code
int main()
{
    int arr[] = {2, 8, 6, 9, 8, 6, 8, 2, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Print frequency of 2 from position 1 to 6
    cout << "Frequency of 2 from 1 to 6 = "
         << findFrequency(arr, n, 1, 6, 2) << endl;
 
    // Print frequency of 8 from position 4 to 9
    cout << "Frequency of 8 from 4 to 9 = "
         << findFrequency(arr, n, 4, 9, 8);
 
    return 0;
}

Time complexity: linear
Space complexity: constant
//  C++ program to get updated array after many array range
// add operation
#include <bits/stdc++.h>
using namespace std;
 
//  Utility method to add value val, to range [lo, hi]
void add(int arr[], int N, int lo, int hi, int val)
{
    arr[lo] += val;
    if (hi != N - 1)
       arr[hi + 1] -= val;
}
 
//  Utility method to get actual array from operation array
void updateArray(int arr[], int N)
{
    //  convert array into prefix sum array
    for (int i = 1; i < N; i++)
        arr[i] += arr[i - 1];
}
 
//  method to print final updated array
void printArr(int arr[], int N)
{
    updateArray(arr, N);
    for (int i = 0; i < N; i++)
        cout << arr[i] << " ";
    cout << endl;
}
 
//  Driver code
int main()
{
    int N = 6;
 
    int arr[N] = {0};
 
    //  Range add Queries
    add(arr, N, 0, 2, 100);
    add(arr, N, 1, 5, 100);
    add(arr, N, 2, 3, 100);
 
    printArr(arr, N);
    return 0;
}

Time complexity: linear
Space complexity: constant
// C++ program for queries of GCD excluding
// given range of elements.
#include<bits/stdc++.h>
using namespace std;
 
 
// Filling the prefix and suffix array
void FillPrefixSuffix(int prefix[], int arr[],
                           int suffix[], int n)
{
    // Filling the prefix array following relation
    // prefix(i) = __gcd(prefix(i-1), arr(i))
    prefix[0] = arr[0];
    for (int i=1 ;i<n; i++)
        prefix[i] = __gcd(prefix[i-1], arr[i]);
 
    // Filling the suffix array following the
    // relation suffix(i) = __gcd(suffix(i+1), arr(i))
    suffix[n-1] = arr[n-1];
 
    for (int i=n-2; i>=0 ;i--)
        suffix[i] = __gcd(suffix[i+1], arr[i]);
}
 
// To calculate gcd of the numbers outside range
int GCDoutsideRange(int l, int r, int prefix[],
                           int suffix[], int n)
{
    // If l=0, we need to tell GCD of numbers
    // from r+1 to n
    if (l==0)
        return suffix[r+1];
 
    // If r=n-1 we need to return the gcd of
    // numbers from 1 to l
    if (r==n-1)
        return prefix[l-1];
    return __gcd(prefix[l-1], suffix[r+1]);
}
 
// Driver function
int main()
{
    int arr[] = {2, 6, 9};
    int n = sizeof(arr)/sizeof(arr[0]);
    int prefix[n], suffix[n];
    FillPrefixSuffix(prefix, arr, suffix, n);
 
    int l = 0, r = 0;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    l = 1 ; r = 1;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    l = 1 ; r = 2;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    return 0;
}

Time complexity: nlogn
Space complexity: linear
// C++ implementation of finding number
// represented by binary subarray
#include <bits/stdc++.h>
using namespace std;
 
// Fills pre[]
void precompute(int arr[], int n, int pre[])
{
    memset(pre, 0, n * sizeof(int));
    pre[n - 1] = arr[n - 1] * pow(2, 0);
    for (int i = n - 2; i >= 0; i--)
        pre[i] = pre[i + 1] + arr[i] * (1 << (n - 1 - i));
}
 
// returns the number represented by a binary
// subarray l to r
int decimalOfSubarr(int arr[], int l, int r,
                    int n, int pre[])
{
    // if r is equal to n-1 r+1 does not exist
    if (r != n - 1)
        return (pre[l] - pre[r + 1]) / (1 << (n - 1 - r));
 
    return pre[l] / (1 << (n - 1 - r));
}
 
// Driver Function
int main()
{
    int arr[] = { 1, 0, 1, 0, 1, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int pre[n];
    precompute(arr, n, pre);
    cout << decimalOfSubarr(arr, 2, 4, n, pre) << endl;
    cout << decimalOfSubarr(arr, 4, 5, n, pre) << endl;
    return 0;
}

Time complexity: linear
Space complexity: linear
// CPP program to perform range queries over range
// queries.
#include <bits/stdc++.h>
#define max 10000
using namespace std;
 
// For prefix sum array
void update(int arr[], int l)
{
    arr[l] += arr[l - 1];
}
 
// This function is used to apply square root
// decomposition in the record array
void record_func(int block_size, int block[],
         int record[], int l, int r, int value)
{
    // traversing first block in range
    while (l < r && l % block_size != 0 && l != 0) {
        record[l] += value;
        l++;
    }
    // traversing completely overlapped blocks in range
    while (l + block_size <= r + 1) {
        block[l / block_size] += value;
        l += block_size;
    }
    // traversing last block in range
    while (l <= r) {
        record[l] += value;
        l++;
    }
}
// Function to print the resultant array
void print(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";   
}
 
// Driver code
int main()
{
    int n = 5, m = 5;
    int arr[n], record[m];
    int block_size = sqrt(m);
    int block[max];
    int command[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },
                          { 2, 1, 2 }, { 2, 1, 3 },
                          { 2, 3, 4 } };
    memset(arr, 0, sizeof arr);
    memset(record, 0, sizeof record);
    memset(block, 0, sizeof block);
 
    for (int i = m - 1; i >= 0; i--) {
 
        // If query is of type 2 then function
        // call to record_func
        if (command[i][0] == 2) {
            int x = i / (block_size);
            record_func(block_size, block, record,
                        command[i][1] - 1, command[i][2] - 1,
                        (block[x] + record[i] + 1));
        }
        // If query is of type 1 then simply add
        // 1 to the record array
        else
            record[i]++;       
    }
 
    // Merging the value of the block in the record array
    for (int i = 0; i < m; i++) {
        int check = (i / block_size);
        record[i] += block[check];
    }
 
    for (int i = 0; i < m; i++) {
        // If query is of type 1 then the array
        // elements are over-written by the record
        //  array
        if (command[i][0] == 1) {
            arr[command[i][1] - 1] += record[i];
            if ((command[i][2] - 1) < n - 1)
                arr[(command[i][2])] -= record[i];           
        }
    }
 
    // The prefix sum of the array
    for (int i = 1; i < n; i++)
        update(arr, i);
     
    // Printing the resultant array
    print(arr, n);
    return 0;
}

Time complexity: logn
Space complexity: linear
// CPP program to count the number of indexes
// in range L R such that Ai = Ai+1
#include <bits/stdc++.h>
using namespace std;
 
// function that answers every query in O(r-l)
int answer_query(int a[], int n, int l, int r)
{
    // traverse from l to r and count
    // the required indexes
    int count = 0;
    for (int i = l; i < r; i++)
        if (a[i] == a[i + 1])
            count += 1;
 
    return count;
}
 
// Driver Code
int main()
{
    int a[] = { 1, 2, 2, 2, 3, 3, 4, 4, 4 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // 1-st query
    int L, R;
    L = 1;
    R = 8;
 
    cout << answer_query(a, n, L, R) << endl;
 
    // 2nd query
    L = 0;
    R = 4;
    cout << answer_query(a, n, L, R) << endl;
    return 0;
}

Time complexity: constant
Space complexity: constant
// CPP program to count the number of indexes
// in range L R such that Ai=Ai+1
#include <bits/stdc++.h>
using namespace std;
const int N = 1000;
 
// array to store count of index from 0 to
// i that obey condition
int prefixans[N];
 
// precomputing prefixans[] array
int countIndex(int a[], int n)
{
    // traverse to compute the prefixans[] array
    for (int i = 0; i < n; i++) {
        if (a[i] == a[i + 1])
            prefixans[i] = 1;
 
        if (i != 0)
            prefixans[i] += prefixans[i - 1];
    }
}
 
// function that answers every query in O(1)
int answer_query(int l, int r)
{
    if (l == 0)
        return prefixans[r - 1];
    else
        return prefixans[r - 1] - prefixans[l - 1];
}
 
// Driver Code
int main()
{
    int a[] = { 1, 2, 2, 2, 3, 3, 4, 4, 4 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // pre-computation
    countIndex(a, n);
 
    int L, R;
 
    // 1-st query
    L = 1;
    R = 8;
 
    cout << answer_query(L, R) << endl;
 
    // 2nd query
    L = 0;
    R = 4;
    cout << answer_query(L, R) << endl;
    return 0;
}

Time complexity: linear
Space complexity: linear
// C++ program to print largest contiguous array sum
#include <bits/stdc++.h>
using namespace std;
 
int maxSubArraySum(int a[], int size)
{
    int max_so_far = INT_MIN, max_ending_here = 0;
 
    for (int i = 0; i < size; i++) {
        max_ending_here = max_ending_here + a[i];
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
 
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}
 
// Driver Code
int main()
{
    int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // Function Call
    int max_sum = maxSubArraySum(a, n);
    cout << "Maximum contiguous sum is " << max_sum;
    return 0;
}

Time complexity: linear
Space complexity: constant
// C++ program to print largest contiguous array sum
 
#include <climits>
#include <iostream>
using namespace std;
 
void maxSubArraySum(int a[], int size)
{
    int max_so_far = INT_MIN, max_ending_here = 0,
        start = 0, end = 0, s = 0;
 
    for (int i = 0; i < size; i++) {
        max_ending_here += a[i];
 
        if (max_so_far < max_ending_here) {
            max_so_far = max_ending_here;
            start = s;
            end = i;
        }
 
        if (max_ending_here < 0) {
            max_ending_here = 0;
            s = i + 1;
        }
    }
    cout << "Maximum contiguous sum is " << max_so_far
         << endl;
    cout << "Starting index " << start << endl
         << "Ending index " << end << endl;
}
 
/*Driver program to test maxSubArraySum*/
int main()
{
    int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
    int n = sizeof(a) / sizeof(a[0]);
    int max_sum = maxSubArraySum(a, n);
    return 0;
}

Time complexity: linear
Space complexity: constant
// C++ program to find maximum
// possible profit with at most
// two transactions
#include <bits/stdc++.h>
using namespace std;
 
// Returns maximum profit with
// two transactions on a given
// list of stock prices, price[0..n-1]
int maxProfit(int price[], int n)
{
    // Create profit array and
    // initialize it as 0
    int* profit = new int[n];
    for (int i = 0; i < n; i++)
        profit[i] = 0;
 
    /* Get the maximum profit with
       only one transaction
       allowed. After this loop,
       profit[i] contains maximum
       profit from price[i..n-1]
       using at most one trans. */
    int max_price = price[n - 1];
    for (int i = n - 2; i >= 0; i--) {
        // max_price has maximum
        // of price[i..n-1]
        if (price[i] > max_price)
            max_price = price[i];
 
        // we can get profit[i] by taking maximum of:
        // a) previous maximum, i.e., profit[i+1]
        // b) profit by buying at price[i] and selling at
        //    max_price
        profit[i]
            = max(profit[i + 1], max_price - price[i]);
    }
 
    /* Get the maximum profit with two transactions allowed
       After this loop, profit[n-1] contains the result */
    int min_price = price[0];
    for (int i = 1; i < n; i++) {
        // min_price is minimum price in price[0..i]
        if (price[i] < min_price)
            min_price = price[i];
 
        // Maximum profit is maximum of:
        // a) previous maximum, i.e., profit[i-1]
        // b) (Buy, Sell) at (min_price, price[i]) and add
        //    profit of other trans. stored in profit[i]
        profit[i] = max(profit[i - 1],
                        profit[i] + (price[i] - min_price));
    }
    int result = profit[n - 1];
 
    delete[] profit; // To avoid memory leak
 
    return result;
}
 
// Driver code
int main()
{
    int price[] = { 2, 30, 15, 10, 8, 25, 80 };
    int n = sizeof(price) / sizeof(price[0]);
    cout << "Maximum Profit = " << maxProfit(price, n);
    return 0;
}

Time complexity: linear
Space complexity: linear
#include <iostream>
#include<climits>
using namespace std;
 
int maxtwobuysell(int arr[],int size) {
    int first_buy = INT_MIN;
      int first_sell = 0;
      int second_buy = INT_MIN;
      int second_sell = 0;
       
      for(int i=0;i<size;i++) {
         
          first_buy = max(first_buy,-arr[i]);//we set prices to negative, so the calculation of profit will be convenient
          first_sell = max(first_sell,first_buy+arr[i]);
          second_buy = max(second_buy,first_sell-arr[i]);//we can buy the second only after first is sold
          second_sell = max(second_sell,second_buy+arr[i]);
       
    }
     return second_sell;
}
 
int main() {
 
    int arr[] = {2, 30, 15, 10, 8, 25, 80};
      int size = sizeof(arr)/sizeof(arr[0]);
      cout<<maxtwobuysell(arr,size);
    return 0;
}

Time complexity: linear
Space complexity: constant