Помоги написать кратко про каждый метод класса вот в подобном виде "SimpleArray(int _size): конструктор класса, создает массив размером _size и присваивает его указателю arr. Также сохраняет значение _size в переменной size."
Вот сам класс:
struct Node
{
    Node* lchild{};
    Node* rchild{};
    int val{};
};

class PersistentArray 
{
private:
    int* base;
    int size;
    std::vector<Node*> versions;
    int max_number_of_elements;
    
    void buildTree(Node* node, int* arr, int l, int r)
    {
        //std::cout << "\nin build with: l = " << l << " r = " << r << "\n";
        //printSlice(l, r);
    
	    if (l == r)
	    {
	        node->val = base[l-1];
		    //std::cout << "in if\t" << node->val << "\n";
	    }
	    else
	    {
		    int m = (l + r) / 2; //std::cout << "m = " << m << "\n";
		    node->lchild = new Node();//std::cout << "\nmaking left child";
		    buildTree(node->lchild, arr, l, m);
		    node->rchild = new  Node();//std::cout << "\nmaking right child";
		    buildTree(node->rchild, arr, m + 1, r);
	    }
    }
    
    void add(Node* to, Node* from, int l, int r, int npos, int nv)
    {
        //std::cout << "to->val = " << to->val << "\t";// << "l: " << to->lchild->val << "\tr: " << to->rchild->val << "\t";
        //std::cout << "from->val = " << from->val << "\t";
        //std::cout << "l = " << l << "\tr = " << r << "\t";
        //std::cout << "npos = " << npos << "\tnvr = " << nv << "\n";

        if (l == r)
        {
            //std::cout << "in if:\t";
            to->val = nv;
            //std::cout << to->val << "\n";
        }
        else
        {
            int m = (l + r) / 2; //std::cout << "m = " << m << "\n";

            if (npos <= m)
            {
                //std::cout << "npos(" << npos << ") <= m(" << m << ") : left manipulations\n";

                to->rchild = from->rchild;
                Node* left = new Node();
                add(left, from->lchild, l, m, npos, nv);
                to->lchild = left;
            }
            else
            {
                //std::cout << "npos(" << npos << ") > m(" << m << ") : right manipulations\n";

                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)
        {
            //std::cout << "l(" << l << ") <= r(" << r << ")\n"; 
            //if (node->lchild != nullptr) std::cout << "node->lchild->val = " << node->lchild->val << "\t";
            //else std::cout << "node->lchild = nullptr\t";
            //if (node->rchild != nullptr) std::cout << "node->rchild->val = " << node->rchild->val << "\n";
            //else std::cout << "node->rchild = nullptr\n";
            return node->val;
        }

        else
        {
            int m = (l + r) / 2;
            if (pos <= m)
            {
                //std::cout << "pos(" << pos << ") <= m(" << m << ")\n"; 
                //std::cout << "node->lchild->val = " << node->lchild->val << "\t";
                //std::cout << "node->rchild->val = " << node->rchild->val << "\n";
                return get(node->lchild, l, m, pos);
            }
            else
            {
                //std::cout << "pos(" << pos << ") > m(" << m << ")\n";
                //std::cout << "node->rchild->val = " << node->rchild->val << "\t";
                //std::cout << "node->lchild->val = " << node->lchild->val << "\n";
                return get(node->rchild, m + 1, r, pos);
            }
        }
    }
    
public:
    PersistentArray(int _size)
    {
        this->base = new int[_size];
        this->size = _size;
        
        versions.push_back(new Node());
        
        int l = 1;
        int r = _size;
        
        buildTree(versions.at(0), base, l, r);
    }

    PersistentArray(int* _arr, int _size) 
    {
        this->base = new int[_size];
        this->size = _size;

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

    ~PersistentArray() 
    {
        delete[] base;
    }

    int getSize() const 
    {
        return this->size;
    }

    int getElement(int _index) const 
    {
        if (_index >= 0 && _index < size)
        {
            return base[_index];
        }
        else 
        {
            /* TODO */
            return -1;
        }
    }

    void setElement(int _index, int _value) 
    {
        if (_index >= 0 && _index < size)
        {
            base[_index] = _value;
            changeVersion(1, _index+1, _value);
        }
        else 
        {
            /* TODO */
        }
    }
    
    void changeVersion(int number_of_version, int newPos, int newVal)
    {
        int l = 1;
        int r = size;
        
        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 = size; 
        
        versions.push_back(new Node());
        add(versions.back(), versions.at(rootPos - 1), l, r, newPos, newVal);
    }
    
    int* getStart()
    {
        return this->base;
    }

    void printSlice(int _left, int _right)
    {
        //std::cout << "in printArr with: size = " << _right - _left + 1 << "\n";
        if (base == nullptr)
        {
            std::cout << "nullptr\n";
            return;
        }

        std::cout << "arr:\t";
        for (int i = _left - 1; i < _right; i++)
        {
            std::cout << base[i] << "\t";
        }
        std::cout << "\n";
    }

    void printAllVersions()
    {
        for (int i = 0; i < versions.size(); i++)
        {
            std::cout << "Version [" << i + 1 << "]: \t";
            for (int j = 1; j < size + 1; j++)
            {
                //std::cout << "n = " << number_of_elements << " i = " << i << " j = " << j << " ";
                std::cout << get(versions.at(i), 1, size, j) << "\t";
            }
            std::cout << "\n";
        }
    }

};