Maintaining a Set with AVL-Tree

/*
Time limit: 3000ms
Memory limit: 256mb

---------------------Copy the following code, complete it and submit---------------------
I, <Your Full Name>, am submitting the assignment for
an individual project.
I declare that the assignment here submitted is original except for
source material explicitly acknowledged, the piece of work, or a part
of the piece of work has not been submitted for more than one purpose
(i.e. to satisfy the requirements in two different courses) without
declaration. I also acknowledge that I am aware of University policy
and regulations on honesty in academic work, and of the disciplinary
guidelines and procedures applicable to breaches of such policy and
regulations, as contained in the University website
http://www.cuhk.edu.hk/policy/academichonesty/.
It is also understood that assignments without a properly signed
declaration by the student concerned will not be graded by the
teacher(s).
*/

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

#define INF -999999

typedef enum {PUT = 1, GET, ERASE, SIZE, PRINT, ERROR_OP} OP;

// AVL tree node
struct AVLTreeNode{
    int value;
    int height;
    int size;
    struct AVLTreeNode* parent;
    struct AVLTreeNode* left;
    struct AVLTreeNode* right;
};

typedef struct AVLTreeNode* TreeNode;

TreeNode createNode(int value) {
    TreeNode node = (TreeNode)malloc(sizeof(struct AVLTreeNode));
    node->height = 1;
    node->left = NULL;
    node->right = NULL;
    node->value = value;
    node->size = 1;
    return node;
}

TreeNode Lchild(TreeNode root) {
    return (root != NULL) ? root->left : NULL;
}

TreeNode Rchild(TreeNode root) {
    return (root != NULL) ? root->right : NULL;
}

bool isEmpty(TreeNode root) {
    return root == NULL;
}

// Return the height of the tree rooted at root
int Height(TreeNode root) {
    if (isEmpty(root)) {
        return 0;
    }
    return root->height;
}

//Return the size of the tree rooted at root
int Size(TreeNode root) {
    if (isEmpty(root)) {
        return 0;
    }
    return root->size;
}

int max(int a, int b) {
    return (a > b) ? a : b;
}

//calculate the properties of the node
void calProperties(TreeNode root)
{
    if (isEmpty(root)) {
        return;
    }
    root->height = 1 + max(Height(root->left), Height(root->right));
    root->size = 1 + Size(root->left) + Size(root->right);
}

void llRotation(TreeNode y) {
    // WRITE YOUR CODE HERE

}

// right-right imbalance
void rrRotation(TreeNode x) {
    // WRITE YOUR CODE HERE

}

// left-right imbalance
void lrRotation(TreeNode y) {
    // WRITE YOUR CODE HERE

}

// right-left imbalance
void rlRotation(TreeNode x) {
    // WRITE YOUR CODE HERE

}

// Calculate the balance factor of a node
int balanceFactor(TreeNode root)
{
    if (root == NULL) {
        return 0;
    }
    return Height(root->left) - Height(root->right);
}


// insert a new node with key into the AVL tree rooted at root
// Remember to update the height of the node and the balance factor of the ancestors of the target node.
// Remember to maintain the sizes of the nodes to support query.
TreeNode insertNode(TreeNode root, int key) {
    if(root == NULL) {
        return createNode(key);
    }
    // WRITE YOUR CODE HERE

}


// if the target node has two children, replace this node with its successor, which is the smallest item in the tree rooted at its right child.
// Remember to update the height of the node and the balance factor of the ancestors of the target node.
// Remember to maintain the sizes of the nodes to support query.
TreeNode deleteNode(TreeNode root, int key) {
    if (root == NULL) {
        return root;
    }
    // WRITE YOUR CODE HERE

}

// Return the number of elements in range [L, R] in the tree rooted at root
int Query(TreeNode root, int L, int R) {
    // WRITE YOUR CODE HERE

}

int main() {

    int n, op, x, L, R;

    TreeNode mySet = NULL;

    scanf("%d", &n);

    for(int i=0; i<n; i++)
    {
        scanf("%d", &op);
        if(op == 1)
        {
            scanf("%d", &x);
            mySet = insertNode(mySet, x);
        }
        else if(op == 2)
        {
            scanf("%d", &x);
            mySet = deleteNode(mySet, x);
        }
        else if(op == 3)
        {
            scanf("%d %d", &L, &R);
            printf("%d\n", Query(mySet, L, R));
        }
    }
    return 0;
}


---------------------------------------End of Code---------------------------------------

## [Maintaining a Set with AVL-Tree]

Your task is to implement a set using an ​AVL-Tree to support the following operations:

1. **Insert** a value x into the set. If x already exists in the set, ignore the operation.

2. **Delete** a value x from the set. If x does not exist in the set, ignore the operation.

3. **Query** the number of elements in the range [L,R] (inclusive) inside the set.


### Input

The first line contain an integer number $n(1\leq n \leq 10^5)$, representing the number of operations.

The next n lines each describe an operation with integers:

  - Operation 1 (Insert): 1 x. Insert a value $x(1\leq x \leq 10^6)$ into the set.

  - Operation 2 (Delete): 2 x. Delete a value $x(1\leq x \leq 10^6)$ from the set.

  - Operation 3 (Query): 3 L R. **Query** the number of elements in the range [L,R] (inclusive) $(1\leq L\leq R \leq 10^6)$.

### Output

For each ​Query (Operation 3), output a single integer — the count of elements in [L,R].

### Example
**Input**
```
7
1 3
1 2
1 5
3 2 4
2 2
3 4 5
3 1 2
```

**Output**
```
2
1
0
```

**Explanation**

Submit