У меня есть класс PersistentArray, который использует персистентное дерево отрезков для хранения версий массива. Этот класс предоставляет методы для построения массива, обновления значений и получения значений на основе индекса. Я хочу сделать нечто аналогичное с таким же API для двусвязного списка (class PersistentDoublyLinkedList). Это возможно в нынешней реализации?
Вот реализация класса PersistentArray с использованием персистентного дерева отрезков:
#include <iostream>
#include <memory>
#include <vector>

class SegmentTree {
public:
    int value;
    std::shared_ptr<SegmentTree> Left, Right;

    SegmentTree(int val) : value(val), Left(nullptr), Right(nullptr) {}
    SegmentTree(std::shared_ptr<SegmentTree> left, std::shared_ptr<SegmentTree> right)
        : Left(left), Right(right) {}
};

class PersistentArray {
private:
    std::shared_ptr<SegmentTree> root;
    int size;

    void build(std::shared_ptr<SegmentTree>& V, int* a, int L, int R) {
        if (L == R) {
            V = std::make_shared<SegmentTree>(a[L]);
            return;
        }
        int Mid = (L + R) / 2;
        std::shared_ptr<SegmentTree> leftChild, rightChild;
        build(leftChild, a, L, Mid);
        build(rightChild, a, Mid + 1, R);
        V = std::make_shared<SegmentTree>(leftChild, rightChild);
    }

    std::shared_ptr<SegmentTree> Update(std::shared_ptr<SegmentTree> V, int L, int R, int pos, int value) {
        if (!V) return nullptr;

        if (L == R) {
            return std::make_shared<SegmentTree>(value);
        }

        int Mid = (L + R) / 2;

        if (pos <= Mid) {
            std::shared_ptr<SegmentTree> newLeft = Update(V->Left, L, Mid, pos, value);
            return std::make_shared<SegmentTree>(newLeft, V->Right);
        } else {
            std::shared_ptr<SegmentTree> newRight = Update(V->Right, Mid + 1, R, pos, value);
            return std::make_shared<SegmentTree>(V->Left, newRight);
        }
    }

    int Get(std::shared_ptr<SegmentTree> V, int L, int R, int pos) {
        if (!V) return 0; // Или любое другое значение, представляющее "не найдено" в вашем случае.

        if (L == R) return V->value;

        int Mid = (L + R) / 2;

        if (pos <= Mid) {
            return Get(V->Left, L, Mid, pos);
        } else {
            return Get(V->Right, Mid + 1, R, pos);
        }
    }

public:
    PersistentArray(int* array, int n) {
        size = n;
        build(root, array, 0, n - 1);
    }

    std::shared_ptr<PersistentArray> Update(int pos, int value) {
        std::shared_ptr<PersistentArray> newArray = std::make_shared<PersistentArray>(*this); // Копируем текущее состояние
        newArray->root = Update(newArray->root, 0, size - 1, pos, value);
        return newArray; // Возвращаем новую версию
    }

    int Get(int pos) {
        return Get(root, 0, size - 1, pos);
    }
};

int main() {
    int a[] = { 1, 2, 3, 4, 5 };
    int n = 5; // Длина массива

    // Создаём персистентный массив
    std::shared_ptr<PersistentArray> array = std::make_shared<PersistentArray>(a, n);

    // Получаем значение по индексу 2
    std::cout << "Value at index 2: " << array->Get(2) << std::endl; // Должно вывести 3

    // Создаем новую версию массива с обновленным значением по индексу 2
    std::shared_ptr<PersistentArray> newArray = array->Update(2, 10);

    // Получаем значение по индексу 2 в новой версии
    std::cout << "Value at index 2 after update: " << newArray->Get(2) << std::endl; // Должно вывести 10

    // Получаем значение в старой версии
    std::cout << "Value at index 2 in old array: " << array->Get(2) << std::endl; // Должно вывести 3

    return 0;
}