Algorithm


Problem Name: Data Structures - Roy and alpha-beta trees

Problem Link: https://www.hackerrank.com/challenges/roy-and-alpha-beta-trees/problem?isFullScreen=true

In this HackerRank in Data Structures - Roy and alpha-beta trees solutions,

Roy has taken a liking to the Binary Search Trees(BST). He is interested in knowing the number of ways an array A of N integers can be arranged to form a BST. Thus, he tries a few combinations, and notes down the numbers at the odd levels and the numbers at the even levels. You're given two values, alpha and beta. Can you calculate the sum of Liking of all possible BST's that can be formed from an array of N integers? Liking of each BST is defined as follows

(sum of numbers on even levels * alpha) - (sum of numbers on odd levels * beta)

Note

  •  The root element is at level 0 ( Even )
  • The elements smaller or equal to the parent element are present in the left subtree, elements greater than or equal to the parent element are present in the right subtree. Explained here

If the answer is no less than 10**9 + 9 output the answer % 10**9 + 9

(If the answer is less than 0, keep adding 10**9 + 9 until the value turns non negative.)

Input Format
The first line of input file contains an integer, T, denoting the number of test cases to follow.
Each testcase comprises of 3 ines.
The first line contains N, the number of integers.
The second line contains two space separated integers, alpha and beta.
The third line contains space separated N integers_, denoting the i**th integer in array A[i]

Output Format
Output T lines. Each line contains the answer to its respective test case.

Constraints

1 <= T <= 10

1 <= N <= 150

1 <= A[i] <= 10**9

1 <= alpha,beta <= 10**9

Sample Input

4
1
1 1
1
2
1 1
1 2
3
1 1
1 2 3
5
1 1
1 2 3 4 5

Sample Output

1
0
6
54

 

 

Code Examples

#1 Code Example with C Programming

Code - C Programming


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MOD 1000000009
int *read_int_array(int n)
{
    int *ret = malloc(n * sizeof(int));
    for( int i = 0 ; i  <  n ; ++i )
    {
        scanf("%d", ret + i);
    }
    return ret;
}
static int intcomp(const void *v1, const void *v2)
{
    return *(const int *)v1 - *(const int *)v2;
}
struct node
{
    long long odd;
    long long even;
    long long count;
};
int solve(int *array, int size, int alpha, int beta)
{
    qsort(array, size, sizeof(int), intcomp);
    struct node **data = malloc(size * sizeof(struct node *));
    for( int i = 0 ; i  <  size ; ++i )
    {
        data[i] = calloc(size, sizeof(struct node));
    }
    for( int s = 0 ; s  < = size ; ++s )
    {
        for( int i = 0 ; i  <  size - s ; ++i )
        {
            for( int j = i ; j  < = i + s ; ++j )
            {
                long long left_count = 1, right_count = 1, left_part_even = 0, right_part_even = 0, left_part_odd = 0, right_part_odd = 0;
                if( j != i )
                {
                    left_part_even = data[i][j - 1].odd;
                    left_part_odd  = data[i][j - 1].even;
                    left_count = data[i][j - 1].count;
                }
                if( j != i + s )
                {
                    right_part_even = data[j + 1][i + s].odd;
                    right_part_odd  = data[j + 1][i + s].even;
                    right_count = data[j + 1][i + s].count;
                }
                long long count = left_count * right_count;
                count %= MOD;
                data[i][i + s].count += count;
                data[i][i + s].count %= MOD;
                long long root = count * array[j];
                root %= MOD;
                data[i][i + s].even += root;
                data[i][i + s].even %= MOD;
                right_part_even *= left_count;
                right_part_even %= MOD;
                right_part_odd  *= left_count;
                right_part_odd  %= MOD;
                left_part_even  *= right_count;
                left_part_even  %= MOD;
                left_part_odd   *= right_count;
                left_part_odd   %= MOD;
                data[i][i + s].even += ( right_part_even + left_part_even );
                data[i][i + s].even %= MOD;
                data[i][i + s].odd += ( right_part_odd + left_part_odd );
                data[i][i + s].odd %= MOD;
            }
        }
    }
    long long even = data[0][size - 1].even, odd  = data[0][size - 1].odd, val = 0;
    val += even * alpha;
    val %= MOD;
    val -= odd * beta;
    val %= MOD;
    for( int i = 0 ; i < size ; ++i )
    {
        free(data[i]);
    }
    free(data);
    return ( val + MOD ) % MOD;
}
int main()
{
    int t, n, m, alpha, beta;
    scanf("%d", &t);
    for( int i = 0 ; i  <  t ; ++i )
    {
        scanf("%d", &n);
        scanf("%d %d", &alpha, &beta);
        int *array = read_int_array(n);
        m = solve(array, n, alpha, beta); 
        printf("%d\n", m>;
    }
    return 0;
}
Copy The Code & Try With Live Editor

#2 Code Example with C++ Programming

Code - C++ Programming


#include <vector>
#include <list>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <ctime>
#include <cassert>
#include <cstring>

#define DEBUG(x) cout << #x << ": " << x << "\n"
using namespace std; // }}}

const int Z = 1000000009;
typedef long long lint;
unordered_map < int, pair<int, int> > MEMO;
vector<lint> C;

pair < int, int> doit(const vector<int>& A, int l, int r)
{
    pair < int, int> res;
    if (l == r)
        return res;

    int p = l * 1000 + r;
    if (MEMO.count(p))
        return MEMO[p];

    for (int i = l; i  <  r; ++i) {
        res.first = (res.first + ((A[i] * C[i - l]) % Z) * C[r - 1 - i]) % Z;

        pair < int, int> left = doit(A, l, i);
        res.second = (res.second + left.first * C[r - 1 - i]) % Z;
        res.first = (res.first + left.second * C[r - 1 - i]) % Z;

        pair < int, int> right = doit(A, i + 1, r);
        res.second = (res.second + right.first * C[i - l]) % Z;
        res.first = (res.first + right.second * C[i - l]) % Z;
    }

    return MEMO[p] = res;
}

int main()
{
    //time_t start, end;
    //time(&start);

    //ifstream cin("test.in");
    //ofstream cout("test.out");
    //fcout.precision(6);
    //fcout.setf(ios::fixed,ios::floatfield);
    ios::sync_with_stdio(false);
    const int M = 151;
    C.resize(M);
    C[0] = C[1] = 1;
    for (int i = 2; i  <  M; ++i) {
        lint& cur = C[i];
        for (int j = 0; j  <  i; ++j) {
            cur = (cur + C[j] * C[i - 1 - j]) % Z;
        }
    }

    int T;
    cin >> T;
    for (int i = 0; i  <  T; ++i) {
        int N;
        cin >> N;
        lint a, b;
        cin >> a >> b;
        vector<int> A(N);
        for (int j = 0; j  <  N; ++j) {
            cin >> A[j];
        }
        MEMO.clear();
        sort(A.begin(), A.end());
        pair < int, int> p = doit(A, 0, N);
        lint res = p.first * a - p.second * b;
        cout << (res % Z + Z) % Z << endl;
    }

    //time(&end);
    //cout << difftime(end, start) << endl;

    return 0;
}
Copy The Code & Try With Live Editor

#3 Code Example with Java Programming

Code - Java Programming


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

class ANKBST02_solver {
    long go(int lo, int hi, int odd) {
        if (lo > hi) {
            return 0;
        }
        if (dp[lo][hi][odd] == -1) {
            long ans = 0;
            for (int root = lo; root  < = hi; root++) {
                //consider all BST in left subtree of root
                ans += (go(lo, root - 1, 1 -odd) * cnt[hi - root - 1 + 1]) % MOD;
                if (ans >= MOD) ans -= MOD;
                if (ans  <  0) ans += MOD;
                //consider all BST in right subtree
                ans += (go(root + 1, hi, 1 -odd) * cnt[root - 1 - lo + 1]) % MOD;
                if (ans >= MOD) ans -= MOD;
                if (ans  <  0) ans += MOD;
                //totTrees is total number of trees considered
                long totTrees = (cnt[hi - root] * cnt[root - lo]) % MOD;
                //remember to add the root as many times for each tree
                ans += (totTrees * ((mul[odd] * a[root]) % MOD)) % MOD;
                if(ans >= MOD) ans -= MOD;
                if (ans < 0) ans += MOD;
            }
            dp[lo][hi][odd] = ans;
        }
        return dp[lo][hi][odd];
    }

    public void solve() throws IOException {
        cnt = generateCatalan(205, MOD);
        cnt[0] = 1;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        int t = Integer.parseInt(br.readLine()>;

        while (t --> 0) {
            int n = Integer.parseInt(br.readLine());
            assert(n  < = 200);
            a = new long[n] ;
            mul = new long[2];
            int i = 0;
            for (StringTokenizer tokenizer = new StringTokenizer(br.readLine()); tokenizer.hasMoreTokens(); ) {
                String s = tokenizer.nextToken();
                mul[i ++] = Integer.parseInt(s);
            }
            mul[1] = -mul[1];
            i = 0;
            for (StringTokenizer tokenizer = new StringTokenizer(br.readLine()); tokenizer.hasMoreTokens(); ) {
                String s = tokenizer.nextToken();
                a[i ++] = Integer.parseInt(s);
            }
            assert(i == n);
            Arrays.sort(a);
            dp = new long[n][n][2];
            for (int j = 0; j  <  n; j++) {
                for (int k = 0; k  <  n; k++) {
                    for (int l = 0; l  <  2; l++) {
                        dp[j][k][l] = -1;
                    }
                }
            }
            pw.println(go(0, n - 1, 0));
        }
        pw.close();
    }

    long[] a;
    long[][][] dp;
    long[] cnt;
    long MOD = (int) (1e9 + 9);
    long[] mul;

    public static long[] generateCatalan(int n, long module) {
        long[] inv = generateReverse(n + 2, module);
        long[] Catalan = new long[n];
        Catalan[1] = 1;
        for (int i = 1; i  <  n - 1; i++) {
            Catalan[i + 1] = (((2 * (2 * i + 1) * inv[i + 2]) % module) * Catalan[i]) % module;
        }
        return Catalan;
    }

    public static long[] generateReverse(int upTo, long module) {
        long[] result = new long[upTo];
        if (upTo > 1)
            result[1] = 1;
        for (int i = 2; i  <  upTo; i++)
            result[i] = (module - module / i * result[((int) (module % i))] % module) % module;
        return result;
    }
}

public class Solution {
    public static void main(String[] args) throws IOException {
            new ANKBST02_solver().solve();
    }
}
Copy The Code & Try With Live Editor

#4 Code Example with Python Programming

Code - Python Programming


MOD = 10**9 + 9
def compute_catalan(N):
    global MOD
    catalan = [0]*(N+1)
    catalan[0] = 1
    for i in range(1, N):
        for j in range(i):
            catalan[i] += catalan[j]*catalan[i-j-1]
        catalan[i] %= MOD
    return catalan
def generate_counts(catalan, N):
    counts = [[[0]*2 for j in range(N)] for i in range(N+1)]
    for i in range(1,N+1):
        for j in range(i):
            counts[i][j][0] += catalan[j]*catalan[i-j-1]
            counts[i][j][0] %= MOD
            for k in range(j):
                counts[i][k][0] += counts[j][k][1]*catalan[i-j-1]
                counts[i][k][1] += counts[j][k][0]*catalan[i-j-1]
                counts[i][k][0] %= MOD
                counts[i][k][1] %= MOD
            for k in range(j+1,i):
                counts[i][k][0] += counts[i-j-1][i-k-1][1]*catalan[j]
                counts[i][k][1] += counts[i-j-1][i-k-1][0]*catalan[j]
                counts[i][k][0] %= MOD
                counts[i][k][1] %= MOD
    return counts
catalan = compute_catalan(150)
T = int(input())
for test_case in range(T):
    N = int(input())
    alpha, beta = (int(x) for x in input().split())
    arr = [int(x) for x in input().split()]
    arr = sorted(arr)
    res = generate_counts(catalan,N)
    s = 0
    for i in range(N):
        s += (alpha*res[N][i][0] - beta*res[N][i][1])*arr[i]
        s %= MOD
    print(s)
Copy The Code & Try With Live Editor
Advertisements

Demonstration


Previous
[Solved] Burger Happiness solution in Hackerrank - Hacerrank solution C, C++, java,js, Python
Next
[Solved] Coloring Tree solution in Hackerrank - Hacerrank solution C, C++, java,js, Python