Problem: 2057B - Gorilla and the Exam
Language: GNU C11


Submission (verdict: Wrong answer on test 2):
//
//  main.c
//  E-2057B
//
//  Created by Tony Abou Zaidan on 17/02/2025.
//
//  Gorilla and the Exam

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef long long ll;

typedef struct _btree_node {
    struct _btree_node* parent;
    struct _btree_node* left;
    struct _btree_node* right;
    ll elem;
    ll h;
    char vis;
}node;

typedef struct _btree {
    node* root;
    int count;
}btree;

ll max(ll a, ll b)
{
    if (a > b) return a;
    return b;
}

btree * create_btree(void)
{
    btree * tree = malloc(sizeof(btree));
    tree->count = 0;
    tree->root = 0;
    return tree;
}

node * create_node(ll val)
{
    node * n = malloc(sizeof(node));
    n->parent = 0;
    n->left = 0;
    n->right = 0;
    n->vis = 0;
    n->elem = val;
    n->h = 1;
    return n;
}

void free_node(node * n)
{
    if(n->left)
        free_node(n->left);
    if(n->right)
        free_node(n->right);
    free(n);
}

void free_btree(btree * b)
{
    if(b->count > 0)
        free_node(b->root);
    free(b);
}

void node_set_height(node * n)
{
    ll lh = n->left ? n->left->h : 0;
    ll rh = n->right ? n->right->h : 0;
    
    n->h = max(lh, rh) + 1;
}

node * rotate_left(node * n)
{
    node * p = n->parent;
    char is_on_right = p != 0 && p->right == n;
    
    node * x = n->right;
    
    if(is_on_right)
    {
        p->right = x;
    }
    else if (p != 0)
    {
        p->left = x;
    }
    
    node * tmp = x->left;
    
    x->left = n;
    n->right = tmp;
    
    n->parent = x;
    x->parent = p;
    
    if(tmp != 0)
        tmp->parent = n;
    
    node_set_height(n);
   
    return x;
}

node * rotate_right(node * n)
{
    node * p = n->parent;
    char is_on_left = p != 0 && p->left == n;
    
    node * x = n->left;
    
    if(is_on_left)
    {
        p->left = x;
    }
    else if (p != 0)
    {
        p->right = x;
    }
    
    node * tmp = x->right;
    
    x->right = n;
    n->left = tmp;
    
    n->parent = x;
    x->parent = p;
    
    if(tmp != 0)
        tmp->parent = n;
    
    node_set_height(n);
   
    return x;
}

void node_add(node * tnode, node * new)
{
    ll diff;
    if(tnode->elem > new->elem)
    {
        if (tnode->left == 0)
        {
            tnode->left = new;
            new->parent = tnode;
        }
        else
        {
            node_add(tnode->left, new);
        }
    }
    else
    {
        if (tnode->right == 0)
        {
            new->parent = tnode;
            tnode->right = new;
        }
        else
        {
            node_add(tnode->right, new);
        }
    }
    
    ll lh = tnode->left ? tnode->left->h : 0;
    ll rh = tnode->right ? tnode->right->h : 0;
    
    tnode->h = max(lh, rh) + 1;
    
    diff = lh - rh;
    
    if (diff > 1)
    {
        rotate_right(tnode);
    }
    else if(diff < -1)
    {
        rotate_left(tnode);
    }
    
}

void btree_add(btree * btree, ll x)
{
    node * node = create_node(x);
    if(btree->count == 0)
        btree->root = node;
    else
        node_add(btree->root, node);
    
    if(btree->root->parent != 0)
        btree->root = btree->root->parent;
    
    btree->count ++;
}

node * traverse(node * n)
{
    if(n->vis)
    {
        if(n->right == 0 || n->right->vis)
        {
            if(n->parent == 0)
                return 0;
            return traverse(n->parent);
        }
        else
        {
            return traverse(n->right);
        }
    }
    else
    {
        if(n->left == 0 || n->left->vis)
        {
            n->vis = 1;
            return n;
        }
        return traverse(n->left);
    }
}


int main(int argc, const char * argv[]) {
    int T;
    int n, k;
    scanf("%d", &T);
    btree * b;
    
    ll tmp;
    ll a[10000];
    ll cc[10000];
    ll seq, c;
    
    while(T--)
    {
        memset(cc, 0, sizeof(cc));
        b = create_btree();
        scanf("%d %d", &n, &k);
        
        for(ll i = 0; i<n; i++)
        {
            scanf("%lld", &tmp);
            btree_add(b, tmp);
        }
        
        node * na = traverse(b->root);
        ll i = 0;
        do {
            a[i++] = na->elem;
            na = traverse(na);
        }while(na != 0);
        
        c = 1;
        seq = 0;
        for(i=1; i<n; i++)
        {
            if(a[i] == a[i-1])
            {
                ++c;
            }
            else
            {
                seq += 1;
                cc[c] += 1;
                c = 1;
            }
        }
        
        seq += 1;
        cc[c] += 1;
        
        i = 1;
        
        while(k > 0 && i <= n)
        {
            if (cc[i] == 0)
            {
                ++i;
                continue;
            }
            
            if (k > cc[i]*i)
            {
                k -= cc[i] * i;
                ++i;
                seq = seq - cc[i];
            }
            else
            {
                seq -= k/i;
                k = 0;
            }
        }
        
        if (seq == 0)
            seq = 1;
        
        printf("%lld\n", seq);

        free_btree(b);
    }
    return 0;
}