Добрый день комьюнити) В Украине среди школьников проводится конкурс МАН, который заключается в написании научных работ, я придумал тему, и хотел бы узнать, будет ли это сильно баян... Пожалуйста, сильно не агртесь, т.к. это работа школьника. Собственно, работа (еще не написанная) будет посвящена структуре данных) Структура позволяет добавлять, находить и удалять элемент x в множестве S, за O(log(x)). Так же на множестве можно поддерживать все ассоциативные операции, такие как: min, max, gcd, xor и прочие (как в сете минимум)... Для этого, воспользуемся бинарным деревом (двоичный бор) и каждому ребру припишем 0 или 1, в зависимости от того левый это ребенок или правый. Предположим нам надо добавить число 116, тогда его двоичное представление 1110100, значит из корня мы идем вдоль ребер 0->0->1->0->1->1->1 и там ставим флаг, что такое число есть. Т.е. так будет выглядеть рекурсивный код:
class node
{
node()
{
next[0] = next[1] = exist = 0;
}
node *next[2]; //левый и правый сын
bool exist;
};
void includeElem(int addNum, node *current) //addNum - добавляемое число, current текущая вершина
{
if (addNum == 0)
{
current->exist = 1;
return;
}
if (current->next[addNum & 1] == 0)
current->next[addNum & 1] = new node();
includeElem((addNum >> 1), current->next[addNum & 1]);
}
В силу того что структура не перестраивается, т.е. корню (и другим вершинам, в которые ведут ребра с пометкой 1) всегда будет соответствовать одно число (корню — 0), то можно ввести функцию на поддереве, как в дереве отрезков, т.е. собирать информацию с детей. Тогда если мы добавляем элемент, то значение этой функции может поменяться только на пути от добавляемой вершины, до корня, значит, когда мы будем возвращаться назад, то на всем пути нам просто надо будет обновить функцию f.
class node
{
node()
{
next[0] = next[1] = exist = valueOfFunc = 0;
}
void update(int number) //число соответствующее этой вершине
{
**valueOfFunf = f(f(next[0]->valueOfFunf, next[0]->valueOfFunf), number); //тут еще надо проверить, существует ли вообще next[0/1], и если в эту вершину ведет ребро с пометкой нуль, тогда number хорошо бы поставить нейтральным элементом**
}
int valueOfFunc;
node *next[2]; //левый и правый сын
bool exist;
};
void includeElem(int addNum, node *current) //addNum - добавляемое число, current текущая вершина
{
if (addNum == 0)
{
current->exist = 1;
return;
}
if (current->next[addNum & 1] == 0)
current->next[addNum & 1] = new node();
includeElem((addNum >> 1), current->next[addNum & 1]);
**current->update();**
}
Так же памяти эта структура будет занимать O(n*log(maxNum)), где n — это количество элементов множества, а maxNum — это максимальное число в нем. Это не трудно заметить из того, что за одно добавление числа x мы добавляем O(log(x)), новых вершин, а т.к. добавлений n — то выходит итоговая асимптотика. Собственно, я бы хотел узнать, имеет ли эта тема на существовании в МАНе?
Молодец, хорошая работа. Такую структуру я еще не встречал.
Замечательно!!! Обычно МАНы пишутся на пустые темы, копированные с википедии. А это серозная работа, достойная внимания. Я искренне надеюсь твою идею оценят)))!!! Удачи)!
круто. но это разве не бор? по крайней мере в решении задачи A тут: http://neerc.ifmo.ru/school/io/archive/20120225/problems-individual-20120225.pdf применялась подобноя идея. другое дело, что хранить в вершинах значение ф-ии — такого я не встречал
Похоже на сжатое дерево отрезков, построенное на [0..MaxValue]
Это немного изменённое (из-за разной длины чисел) сжатое дерево отрезков на всех числах от 0 до maxNum. Любое сбалансированное бинарное дерево будет решать поставленную задачу лучше (log(n) вместо log(maxNum) и памяти O(n)). Конечно, у вас "бонус" в быстром времени работы для мелких чисел, но его тоже легко победить, если сделать log(maxNum) деревьев. Не знаю, что такое МАН, но советую вам улучшить вашу структуру — и реализация проще будет, и работать будет гораздо быстрее.
Суть в том, что МАН — это мини-научная работа. И если что-то изобретать, то обязательно это что-то должно быть чем-то лучше существующих и, не исключено, что чем-то оно будет хуже. Так я понимаю, что в скорости оно сету проиграет на больших числах и, для компенсации, ввел поддержку функции.
Ну оно у бинарных деревьев ни в чём не выиграет — там функция точно так же добавляется, храним в каждой вершине ответ для поддерева, при изменении пересчитываем.
Если там участники действительно предлагают что-то в computer science, что в чём-то лучше всего существующего, — очень хотелось бы посмотреть на примеры работ, т.к. это довольно круто :)
Да, согласен, в бинарных деревьях тоже можно спокойно обновить значение функции. Но тогда в плюсы можно написать, что оно работает быстрее когда много маленьких чисел =)
А по поводу работ на этом МАНе, там ооочень мало нормальных работ, почти нет. Конкурс проводится в 3 тура, заочный (ты им посылаешь письменный вариант работы), контрольная (математика) и защита.. Ну и все там решает контрольная, если нормальная работа.. В прошлом году я пошел в "обучающие программы" и писал работу про визуализацию нейронных сетей с кнопочками "Создать", "Обучить", "Тестировать", свою нейро-сетку и эта лажа заняла 1-ое место. Но в этом году хочется написать что-то нормальное..
На маленьких числах вы тоже не обгоните бинарные деревья — как я написал в первом комменте, можно сделать log(maxNum) деревьев — по одному для каждой длины числа в битах. Тогда получим на операцию log(количества чисел в множестве той же длины, что и x), что <=log(x).
Что там мало нормальных работ — я не удивлён, делать в науке что-то новое непросто; даже если там O(1) работ, которые в чём-то лучше всего существующего, — это уже очень круто.
Оценку по памяти точнее определить как O(min(MaxNum,N*log(MaxNum))).
Минус в ограниченности: элементы — целые неотриц-ые числа, можно расширить и до вещетвенных, наверно, по той же схеме. Еще один минус что результаты этих полезных функций вычисляются только для строгих множеств элементов (которые опред-ся их двоичными представлениями)
Есть ли такое в Мане врядли тут кто-то может сказать, не проще им послать на рецензию?
По-моему уровень работы хороший для школьника и для Мана, но научной новизны конечно нет)