51

(3 ответов, оставленных в Feedback)

Я почему-то сомневаюсь, что искать максимум на отрезке таким образом будет быстрее, чем не рекурсивным деревом отрезков. Да и пишется оно точно не длиннее.

52

(7 ответов, оставленных в Problems)

Очевидно, что данную точку следует искать на границе прямоугольника, причем ее икс координата будет совпадать с икс координатой левой или правой стороны одного из прямоугольников, а так же игрек координата будет совпадать с игрек координатой нижней или верхней стороны одного из прямоугольников (не обязательно того же самого).

Отсортируем все икс координаты по возрастанию и сделаем заметание вертикальной прямой. Заведем дерево отрезков по игрек координатам, которые встречались среди игрек координат прямоугольников. Когда мы встречаем левую границу прямоугольника, увеличиваем в дереве отрезков значения на отрезке от нижнего до верхнего игрека на 1. Когда встречаем правую границу - уменьшаем значения. После каждой такой операции смотрим максимум в дереве. Тогда максимум среди всех таких максимумов и будет искомой точкой. Сложность O(NlogN).

Можно подбирать ребра по одному. Просто добавляем ребро, а затем потоком проверяем, можем ли мы остальное достроить так чтобы все ограничения выполнялись. Нам не нужно каждый раз поток полностью пересчитывать, достаточно поиска одного дополняющего пути. Сложность O(E^2), хотя константа, думаю, будет маленькой.

54

(3 ответов, оставленных в Algo)

Во-первых, O(N^2*M) это лишь порядок количества операций, т.е. там N^2*M*C, где C может быть <1.
Во-вторых, столько операций выполняется в худшем случае, в среднем же алгоритм работает быстро.
Вот ссылка на статью, где описан худший случай для алгоритма Диница: http://deepblue.lib.umich.edu/bitstream … 000617.pdf.

Все такие вершины принадлежат компонентам реберной двусвязности размера >=3. А эти компоненты можно легко за О(Н+М) найти.

56

(9 ответов, оставленных в Problems)

Да нет, я не говорил что это необычное. Просто я честно ответил, где вычитал этот метод smile До этого писал всегда с массивом векторов смежных вершин.

57

(9 ответов, оставленных в Problems)

Acmefan пишет:

to KADR:
Прикольная модификация списка ребер.
Сразу возникает жадный вопрос. Где такое вычитал? Может там еще че интересное накопаю smile

Вычитал я это когда-то давно в коде ACRush на кодджеме.

58

(32 ответов, оставленных в Problems)

coder.ua пишет:

Добавление у меня такое же, но я кажется понял в чём ошибка у меня: ты наверное перебираешь все подстроки по длине сначала, а потом очищаешь список. Я же всё кидал в один список...:/
Большое спасибо за помощь!

Да, я после проверки очередной длины очищаю хешсет.

59

(32 ответов, оставленных в Problems)

Для этой задачи написал вот такой простенький хешсет, который добавляет элемент если такого в нем не было и возвращает 1 или 0 в зависимости от того, был ли добавлен элемент.

int last[MOD],nx[5001];
unsigned ll key[5001];

inline bool add(unsigned ll h)
{
    for (int w=last[h%MOD];w>=0;w=nx[w])
    {
        if (key[w]==h) return 0;
    }
    int o=h%MOD;
    key[k]=h;
    nx[k]=last[o];
    last[o]=k++;
    return 1;
}

60

(32 ответов, оставленных в Problems)

Ради интереса только что сдал с лонг лонговским хешом и ручным хешсетом.

61

(32 ответов, оставленных в Problems)

Ну так это уже не квадрат, а N^2logN, причем операции с вектором лонг лонгов. Многовато.

62

(32 ответов, оставленных в Problems)

Можно решать, например, так (описано в самом низу страницы).

Всегда пишу Дейкстру с STL-евской priority_queue. На этой задаче работало 0.234 сек.

64

(7 ответов, оставленных в Problems)

Можно избавиться от cin/cout, если и так не пройдет - заменить map на отсортированный массив или хешмап.

tereshinvs пишет:

Ой... Виноват smile

Вершин не больше 100, дорог не более 10^4, необходимо найти любой такой путь между указанными вершинами.
А вообще это задача 1527 с тимуса. Понятно, что бинпоиск по высоте, а вот дальше не очень понятно, что делать...

Может быть смысл в том, что у нас денег не больше чем 10...

Сделаем бинпоиск по высоте.

Стоимости дорог 0 или 1, поэтому как бы мы не ехали - самый дорогой путь будет не дороже чем 100. Значит, можем построить новый граф, где вершинами будут пары (номер,стоимость дороги сюда). Запустим алгоритм Дейкстры по этому графу, минимизируя суммарное время проезда. Затем просто проверим для всех подходящих пар (конечная вершина, стоимость не больше допустимой) времена, требуемые чтобы достигнуть такой пары. Если подходящее есть - говорим что такая высота нам подходит, иначе говорим что не подходит.

66

(4 ответов, оставленных в Algo)

Нет, в массиве g хранятся не 0 или 1, а списки смежных вершин. То есть g[v] это список всех вершин, которые смежные с v.

Из первого поста я понял только то что нужно решить систему. Если хочешь чтобы тебе помогли с решением задачи - формулируй условие четко и понятно, иначе вряд ли кто-то станет разбираться.

Функция имеет какой-то конкретный вид или может быть вообще произвольной? Под 64 неизвестными имеется ввиду, что у функции 64 аргумента?

http://e-maxx.ru/algo/linear_systems_gauss

69

(4 ответов, оставленных в Algo)

paul пишет:

Алгоритм с сайта работает не так как надо sad Или у меня руки кривые
Можно простой пример его работы ?

Если что-то конкретно непонятно - спросите, возможно вам помогут. Алгоритм довольно простой, попробуйте нарисовать граф на бумажке и просимулировать его работу на нем.

70

(4 ответов, оставленных в Problems)

coder.ua пишет:

Спасибо, но я не пойму зачем нам сумма длин путей до LCA. Возможно таким образом  можно найти максимальное ребро на цикле или я что-то неправильно понимаю понимаю?

В плане - сумма длин это будет сумма ребер цикла. Я когда писал, забыл о максимальном ребре smile. Для его нахождения нужно просто найти максимум из всех ребер от А до LCA и от B до LCA.

Чтобы сложность вышла линейной, можно после нахождения LCA, запустить дфс и для каждой вершины A в нем перебрать все ребра инцидентные ей, которые не вошли в миностов, для каждого второго конца B взять уже найденный LCA и затем посчитать максимум среди всех ребер от вершины до LCA. Так как мы находимся в дфсе, список вершин, в которых мы побывали но еще не вышли из рекурсии образует путь, причем LCA и A лежат в этом пути, а A является последней вершиной в нем. Можно в стеке хранить возрастающую последовательность номеров ребер и при спуске в рекурсию (добавлению нового ребра) удалять ребра из вершины стека до тех пор, пока они не превышают данное. Затем, максимум от LCA до A сводится к поиску номера i в стеке, такого что i-е ребро лежит ниже на пути чем LCA, а i-1 -е ребро уже выше. Очевидно, что это ребро и будет искомым максимумом. Можно, конечно, это искать бинпоиском, но так как за NlogN можно и проще сделать, я расскажу как это делать за O(1) в среднем.

Когда ребро выпихивается другим ребром из стека, сохраним для него ссылку на то ребро, которое его выпихнуло. Затем, когда выпихнется и то ребро - мы должны изменить ссылку. Это можно делать системой непересекающихся множеств.

Теперь мы научились извлекать максимум и спускаться ниже в рекурсию. Остается вопрос - что делать, когда нам нужно подниматься? При спуске мы сделали О(К) изменений памяти, значит, мы за О(К) можем их всех откатить, вернув в стек ребра и изменив состояние системы непересекающихся множеств. Таким образом, получаем алгоритм, который за О(E) в оффлайне находит все максимумы ребер от A до LCA(A,B), где B - второй конец ребра невошедшего в миностов, инцидентного A.


Если же хочется O(NlogN) - можно просто для каждой вершины предпосчитать максимальное ребро до первой, второй, четвертой и т.д. вершин на пути от данной вершины к корню дерева.

71

(7 ответов, оставленных в Problems)

Да, это похоже на правду. Только при такой реализации predcessor() выполняется за O(log^2(N)). Чтобы был просто логарифм нужно в начале еще предпосчитать для каждого числа от 1 до maxheight наибольшую степень двойки, не превышающую его.

72

(4 ответов, оставленных в Problems)

Я не знаю другого алгоритма, но я знаю как этот написать так чтобы он работал быстро. А именно: при добавлении одного ребра мы можем найти LCA двух его концов в MST и посчитать сумму длин путей до LCA. Так как все такие запросы заранее известны, можно второй миностов найти за O(E) при помощи алгоритма Тарьяна при построенном первом миностове.

73

(1 ответов, оставленных в Offtopic)

int go(...);
int ok(...);
...
int go(...) { ... ok(...) ... }
int ok(...) { ... }

74

(5 ответов, оставленных в Problems)

coder.ua пишет:

Первую можно сделать сканирующей прямой,предварительно отсортировав все окружности по одной из координат.
Для второй,мне кажется, нужно найти пару самых отдалённых друг от друга точек.Расстояние между ними - диаметр окружности , середина отрезка ,который соединяет эти точки, - центр окружности.

Для второй задачи это не верно, даже если точки 3. Если треугольник не прямоугольный, то центр описанной окружности не будет лежать на стороне.
Насчет первой - там нужно найти точку пересечения окружностей или кругов? Если окружностей, то там все просто. Для кругов за НлогН скорее всего сканлайном, но пока не понятно как сделать так чтобы не хранить многоугольник с дугами вместо сторон и не обновлять его как-то быстро.

75

(3 ответов, оставленных в Problems)

Пусть f(i,l,r) - наименьшее количество использованных строк, требуемое чтобы представить подстроку N начинающуюся в позиции l и заканчивающуюся в r, причем использоваться могут только маленькие строки с номерами от 1 до i. Тогда легко выразить f(i,l,r) через f(i-1,l,r') и f(i-1,l',r) просто перебрав все позиции куда мы ставим текущее число (или не ставим его вообще) и разделяем нашу строку на 2.