Given an array arr of size N. The task is to count the number of triplets in the array such that a[i]>a[j]>a[k] and i<j<k
Examples:
Input : arr[] = {10, 8, 3, 1}
Output : 4
The triplets are:
1, 3, 8
1, 3, 10
1, 8, 10
3, 8, 10Input : arr[] = {88, 64, 45, 21, 54}
Output : 5
Prerequisites: Count inversions
Approach:
- Find the greater_left array. greater_left[i] represents the number of elements greater than a[i] and in left side of it ( from 0 to i-1 ).
- Find the smaller_right array. smaller_right[i] represents the number of elements smaller than a[i] and in right side to it ( from i+1 to n-1 )
- The final answer will be the sum of the product of greater_left[i] and smaller_right[i] for every index.
Below is the implementation of the above approach:
C++
// CPP program to find triplets // a[i]>a[j]>a[k] and i<j<k #include<bits/stdc++.h> using namespace std;
// Updates a node in Binary Index Tree (BIT) // at given index(i) in BIT. The given value // 'val' is added to BITree[i] and // all of its ancestors in tree. void update( int BIT[], int n, int i, int val)
{ for (; i <= n; i += (i & -i)) {
BIT[i] += val;
}
} // Returns sum of arr[0..i]. This function // assumes that the array is preprocessed // and partial sums of array elements are // stored in BIT[]. int query( int BIT[], int i)
{ int sum = 0;
for (; i > 0; i -= (i & -i)) {
sum += BIT[i];
}
return sum;
} // Converts an array to an array with values from 1 to n // and relative order of smaller and greater elements // remains same. For example, {7, -90, 100, 1} is // converted to {3, 1, 4 ,2 } void Convert( int arr[], int n)
{ int temp[n];
for ( int i = 0; i < n; i++) {
temp[i] = arr[i];
}
sort(temp, temp + n);
for ( int i = 0; i < n; i++) {
arr[i] = lower_bound(temp, temp + n, arr[i]) - temp + 1;
}
} // Function to find triplets int getCount( int arr[], int n)
{ // Decomposition
Convert(arr, n);
int BIT[n + 1] = { 0 };
int smaller_right[n + 1] = { 0 };
int greater_left[n + 1] = { 0 };
// Find all right side smaller elements
for ( int i = n - 1; i >= 0; i--) {
smaller_right[i] = query(BIT, arr[i]-1);
update(BIT, n, arr[i], 1);
}
for ( int i = 0; i <= n; i++) {
BIT[i] = 0;
}
// Find all left side greater elements
for ( int i = 0; i < n; i++) {
greater_left[i] = i - query(BIT, arr[i]);
update(BIT, n, arr[i], 1);
}
// Find the required answer
int ans = 0;
for ( int i = 0; i < n; i++) {
ans += greater_left[i] * smaller_right[i];
}
// Return the required answer
return ans;
} // Driver code int main()
{ int arr[] = { 7, 3, 4, 3, 3, 1};
int n = sizeof (arr) / sizeof (arr[0]);
cout << getCount(arr, n) << endl;
return 0;
} |
Java
import java.io.*;
import java.util.*;
class GFG {
public static int lower( int a[], int x) //Returns leftest index of x in sorted arr else n
{ //If not present returns index of just greater element
int n = a.length;
int l = 0 ;
int r = n - 1 ;
int ans = n;
while (l <= r)
{
int m = (r - l) / 2 + l;
if (a[m] >= x)
{
ans = m;
r = m - 1 ;
}
else
{
l = m + 1 ;
}
}
return ans;
}
// Returns sum of arr[0..i]. This function
// assumes that the array is preprocessed
// and partial sums of array elements are
// stored in BIT[].
public static int query( int BIT[], int i)
{
int sum = 0 ;
for (; i > 0 ; i -= (i & -i)) {
sum += BIT[i];
}
return sum;
}
// Converts an array to an array with values from 1 to n
// and relative order of smaller and greater elements
// remains same. For example, {7, -90, 100, 1} is
// converted to {3, 1, 4 ,2 }
public static void Convert( int arr[], int n)
{
int temp[]= new int [n];
for ( int i = 0 ; i < n; i++) {
temp[i] = arr[i];
}
Arrays.sort(temp);
for ( int i = 0 ; i < n; i++) {
arr[i] = lower(temp, arr[i]) + 1 ;
}
}
// Updates a node in Binary Index Tree (BIT)
// at given index(i) in BIT. The given value
// 'val' is added to BITree[i] and
// all of its ancestors in tree.
public static void update( int BIT[], int n, int i, int val)
{
for (; i <= n; i += (i & -i)) {
BIT[i] += val;
}
}
// Function to find triplets
public static int getCount( int arr[], int n)
{
// Decomposition
Convert(arr, n);
int BIT[] = new int [n+ 1 ];
int smaller_right[] = new int [n+ 1 ];
int greater_left[] = new int [n+ 1 ];
for ( int i= 0 ;i<n+ 1 ;i++){
BIT[i]= 0 ;
smaller_right[i]= 0 ;
greater_left[i]= 0 ;
}
// Find all right side smaller elements
for ( int i = n - 1 ; i >= 0 ; i--) {
smaller_right[i] = query(BIT, arr[i]- 1 );
update(BIT, n, arr[i], 1 );
}
for ( int i = 0 ; i <= n; i++) {
BIT[i] = 0 ;
}
// Find all left side greater elements
for ( int i = 0 ; i < n; i++) {
greater_left[i] = i - query(BIT, arr[i]);
update(BIT, n, arr[i], 1 );
}
// Find the required answer
int ans = 0 ;
for ( int i = 0 ; i < n; i++) {
ans += greater_left[i] * smaller_right[i];
}
// Return the required answer
return ans;
}
public static void main (String[] args) {
int arr[] = { 7 , 3 , 4 , 3 , 3 , 1 };
int n = 6 ;
System.out.println(getCount(arr, n));
}
} // this code is contributed by Manu Pathria |
Python3
# Python3 program to find triplets # a[i]>a[j]>a[k] and i<j<k from bisect import bisect_left as lower_bound
# Updates a node in Binary Index Tree (BIT) # at given index(i) in BIT. The given value # 'val' is added to BITree[i] and # all of its ancestors in tree. def update(BIT, n, i, val):
while i < = n:
BIT[i] + = val
i + = (i & - i)
# Returns sum of arr[0..i]. This function # assumes that the array is preprocessed # and partial sums of array elements are # stored in BIT[]. def query(BIT, i):
summ = 0
while i > 0 :
summ + = BIT[i]
i - = (i & - i)
return summ
# Converts an array to an array with values # from 1 to n and relative order of smaller # and greater elements remains same. For example, # {7, -90, 100, 1} is converted to {3, 1, 4 ,2 } def convert(arr, n):
temp = [ 0 ] * n
for i in range (n):
temp[i] = arr[i]
temp.sort()
for i in range (n):
arr[i] = lower_bound(temp, arr[i]) + 1
# Function to find triplets def getCount(arr, n):
# Decomposition
convert(arr, n)
BIT = [ 0 ] * (n + 1 )
smaller_right = [ 0 ] * (n + 1 )
greater_left = [ 0 ] * (n + 1 )
# Find all right side smaller elements
for i in range (n - 1 , - 1 , - 1 ):
smaller_right[i] = query(BIT, arr[i] - 1 )
update(BIT, n, arr[i], 1 )
for i in range (n + 1 ):
BIT[i] = 0
# Find all left side greater elements
for i in range (n):
greater_left[i] = i - query(BIT, arr[i])
update(BIT, n, arr[i], 1 )
# Find the required answer
ans = 0
for i in range (n):
ans + = greater_left[i] * smaller_right[i]
# Return the required answer
return ans
# Driver Code if __name__ = = "__main__" :
arr = [ 7 , 3 , 4 , 3 , 3 , 1 ]
n = len (arr)
print (getCount(arr, n))
# This code is contributed by # sanjeev2552 |
C#
// C# implementation of the approach using System;
class GFG
{ public static int lower( int [] a, int x) //Returns leftest index of x in sorted arr else n
{ //If not present returns index of just greater element
int n = a.Length;
int l = 0;
int r = n - 1;
int ans = n;
while (l <= r)
{
int m = (r - l) / 2 + l;
if (a[m] >= x)
{
ans = m;
r = m - 1;
}
else
{
l = m + 1;
}
}
return ans;
}
// Returns sum of arr[0..i]. This function
// assumes that the array is preprocessed
// and partial sums of array elements are
// stored in BIT[].
public static int query( int [] BIT, int i)
{
int sum = 0;
for (; i > 0; i -= (i & -i)) {
sum += BIT[i];
}
return sum;
}
// Converts an array to an array with values from 1 to n
// and relative order of smaller and greater elements
// remains same. For example, {7, -90, 100, 1} is
// converted to {3, 1, 4 ,2 }
public static void Convert( int [] arr, int n)
{
int [] temp = new int [n];
for ( int i = 0; i < n; i++) {
temp[i] = arr[i];
}
Array.Sort(temp);
for ( int i = 0; i < n; i++) {
arr[i] = lower(temp, arr[i]) + 1;
}
}
// Updates a node in Binary Index Tree (BIT)
// at given index(i) in BIT. The given value
// 'val' is added to BITree[i] and
// all of its ancestors in tree.
public static void update( int [] BIT, int n, int i, int val)
{
for (; i <= n; i += (i & -i)) {
BIT[i] += val;
}
}
// Function to find triplets
public static int getCount( int [] arr, int n)
{
// Decomposition
Convert(arr, n);
int [] BIT = new int [n + 1];
int [] smaller_right = new int [n + 1];
int [] greater_left = new int [n + 1];
for ( int i = 0; i < n + 1; i++)
{
BIT[i] = 0;
smaller_right[i] = 0;
greater_left[i] = 0;
}
// Find all right side smaller elements
for ( int i = n - 1; i >= 0; i--)
{
smaller_right[i] = query(BIT, arr[i]-1);
update(BIT, n, arr[i], 1);
}
for ( int i = 0; i <= n; i++)
{
BIT[i] = 0;
}
// Find all left side greater elements
for ( int i = 0; i < n; i++)
{
greater_left[i] = i - query(BIT, arr[i]);
update(BIT, n, arr[i], 1);
}
// Find the required answer
int ans = 0;
for ( int i = 0; i < n; i++)
{
ans += greater_left[i] * smaller_right[i];
}
// Return the required answer
return ans;
}
// Driver code
public static void Main ()
{
int [] arr = { 7, 3, 4, 3, 3, 1};
int n = 6;
Console.WriteLine(getCount(arr, n));
}
} // This code is contributed by target_2. |
Javascript
<script> // JavaScript program to find triplets // a[i]>a[j]>a[k] and i<j<k // Updates a node in Binary Index Tree (BIT) // at given index(i) in BIT. The given value // 'val' is added to BITree[i] and // all of its ancestors in tree. function update(BIT, n, i, val) {
for (; i <= n; i += (i & -i)) {
BIT[i] += val;
}
} // Returns sum of arr[0..i]. This function // assumes that the array is preprocessed // and partial sums of array elements are // stored in BIT[]. function query(BIT, i) {
let sum = 0;
for (; i > 0; i -= (i & -i)) {
sum += BIT[i];
}
return sum;
} //Returns leftest index of x in sorted arr else n //If not present returns index of just greater element function lower(a, x) {
let n = a.length;
let l = 0;
let r = n - 1;
let ans = n;
while (l <= r) {
let m = Math.floor((r - l) / 2) + l;
if (a[m] >= x) {
ans = m;
r = m - 1;
}
else {
l = m + 1;
}
}
return ans;
} // Converts an array to an array with values from 1 to n // and relative order of smaller and greater elements // remains same. For example, {7, -90, 100, 1} is // converted to {3, 1, 4 ,2 } function Convert(arr, n) {
let temp = new Array(n);
for (let i = 0; i < n; i++) {
temp[i] = arr[i];
}
temp.sort((a, b) => a - b);
for (let i = 0; i < n; i++) {
arr[i] = lower(temp, arr[i]) + 1;
}
} // Function to find triplets function getCount(arr, n) {
// Decomposition
Convert(arr, n);
let BIT = new Array(n + 1).fill(0);
let smaller_right = new Array(n + 1).fill(0);
let greater_left = new Array(n + 1).fill(0);
// Find all right side smaller elements
for (let i = n - 1; i >= 0; i--) {
smaller_right[i] = query(BIT, arr[i] - 1);
update(BIT, n, arr[i], 1);
}
for (let i = 0; i <= n; i++) {
BIT[i] = 0;
}
// Find all left side greater elements
for (let i = 0; i < n; i++) {
greater_left[i] = i - query(BIT, arr[i]);
update(BIT, n, arr[i], 1);
}
// Find the required answer
let ans = 0;
for (let i = 0; i < n; i++) {
ans += greater_left[i] * smaller_right[i];
}
// Return the required answer
return ans;
} // Driver code let arr = [7, 3, 4, 3, 3, 1]; let n = arr.length; document.write(getCount(arr, n) + "<br>" );
// This code is contributed by _saurabh_jaiswal </script> |
Output
8
Time Complexity: O(N*LogN)
Auxiliary Space: O(N)