Помоги написать кратко про каждый метод класса вот в подобном виде “SimpleArray(int _size): конструктор класса, создает массив размером _size и присваивает его указателю arr. Также сохраняет значение _size в переменной size.”
Вот сам класс:
struct AA_node
{
    int key;
    int value;
    AA_node* left;
    AA_node* right;

    AA_node(int k, int v) : key(k), value(v), left(nullptr), right(nullptr) {}
};

struct Node
{
    Node* lchild{};
    Node* rchild{};
    int val{};
};

class PersistentAssociativeArray
{
private:
    AA_node* base;
    
    std::vector<Node*> versions;

    AA_node* insertRecursive(AA_node* current, int key, int value)
    {
        if (current == nullptr)
        {
            return new AA_node(key, value);
        }

        if (key < current->key)
        {
            current->left = insertRecursive(current->left, key, value);
        }
        else if (key > current->key)
        {
            current->right = insertRecursive(current->right, key, value);
        }
        else
        {
            current->value = value;
        }

        return current;
    }

    AA_node* searchRecursive(AA_node* current, int key)
    {
        if (current == nullptr || current->key == key)
        {
            return current;
        }

        if (key < current->key)
        {
            return searchRecursive(current->left, key);
        }

        return searchRecursive(current->right, key);
    }

    void inorderRecursive(AA_node* current)
    {
        if (current != nullptr)
        {
            inorderRecursive(current->left);
            std::cout << current->key << " : " << current->value << std::endl;
            inorderRecursive(current->right);
        }
    }

    int sizeRecursive(AA_node* current)
    {
        if (current == nullptr)
        {
            return 0;
        }

        return 1 + sizeRecursive(current->left) + sizeRecursive(current->right);
    }

    void printSliceRecursive(AA_node* current, int left, int right)
    {
        if (current == nullptr)
        {
            return;
        }

        if (current->key >= left && current->key <= right)
        {
            std::cout << current->key << " : " << current->value << std::endl;
        }

        if (current->key > right)
        {
            printSliceRecursive(current->left, left, right);
        }
        else if (current->key < left)
        {
            printSliceRecursive(current->right, left, right);
        }
        else
        {
            printSliceRecursive(current->left, left, right);
            printSliceRecursive(current->right, left, right);
        }
    }
    
    void buildTree(Node* node, int l, int r)
    {
        if (l == r)
        {
            node->val = getElement(l - 1);
        }
        else
        {
            int m = (l + r) / 2; //std::cout << "m = " << m << "\n";
            node->lchild = new Node();//std::cout << "\nmaking left child";
            buildTree(node->lchild, l, m);
            node->rchild = new  Node();//std::cout << "\nmaking right child";
            buildTree(node->rchild, m + 1, r);
        }
    }
    
    void add(Node* to, Node* from, int l, int r, int npos, int nv)
    {
        if (l == r)
        {
            to->val = nv;
        }
        else
        {
            int m = (l + r) / 2; //std::cout << "m = " << m << "\n";

            if (npos <= m)
            {
                to->rchild = from->rchild;
                Node* left = new Node();
                add(left, from->lchild, l, m, npos, nv);
                to->lchild = left;
            }
            else
            {
                to->lchild = from->lchild;
                Node* right = new Node();
                add(right, from->rchild, m + 1, r, npos, nv);
                to->rchild = right;
            }
        }
    }

    int get(Node* node, int l, int r, int pos)
    {
        if (l == r)
        {
            return node->val;
        }

        else
        {
            int m = (l + r) / 2;
            if (pos <= m)
            {
                return get(node->lchild, l, m, pos);
            }
            else
            {
                return get(node->rchild, m + 1, r, pos);
            }
        }
    }

public:
    PersistentAssociativeArray() : base(nullptr) {}

    PersistentAssociativeArray(AA_node* _root)
    {
        this->base = _root;
    }
    
    PersistentAssociativeArray(int _key, int _value)
    {
        base = new AA_node(_key, _value);
        
        versions.push_back(new Node());
        
        int l = 1;
        int r = 1;

        buildTree(versions.at(0), l, r);
    }
    
    PersistentAssociativeArray(int* _arr, int _size)
    {
        base = nullptr;
        
        versions.push_back(new Node());
        
        for (int i = 0; i < _size; i++)
        {
            insert(i, _arr[i]);
        }
        
        int l = 1;
        int r = _size;

        buildTree(versions.at(0), l, r);
    }

    void insert(int _key, int _value)
    {
        base = insertRecursive(base, _key, _value);
        
        int l = 1;
        int r = getSize();

        buildTree(versions.at(0), l, r);
    }

    int getElement(int key)
    {
        AA_node* node = searchRecursive(base, key);

        if (node != nullptr)
        {
            return node->value;
        }

        return -1;  // Return -1 if the key is not found
    }

    void inorder()
    {
        inorderRecursive(base);
    }

    int getSize()
    {
        return sizeRecursive(base);
    }

    void printSlice(int left, int right)
    {
        printSliceRecursive(base, left - 1, right - 1);
    }

    AA_node* getStart()
    {
        return base;
    }
    
    void printAllVersions()
    {
        int n = getSize();
        for (int i = 0; i < versions.size(); i++)
        {
            std::cout << "Version [" << i + 1 << "]: \t";
            for (int j = 1; j < n + 1; j++)
            {
                std::cout << get(versions.at(i), 1, n, j) << "\t";
            }
            std::cout << "\n";
        }
    }
    
    void changeVersion(int number_of_version, int newPos, int newVal)
    {
        int l = 1;
        int r = getSize();

        add(versions[number_of_version - 1], versions.at(number_of_version - 1), l, r, newPos, newVal);
    }

    void addVersion(int rootPos, int newPos, int newVal)
    {
        int l = 1;
        int r = getSize();

        versions.push_back(new Node());
        add(versions.back(), versions.at(rootPos - 1), l, r, newPos, newVal);
    }
};