Дана довольно банальная задача. Дан массив состоящий из N чисел (N<=10^5). Нужно для каждого числа вывести кол-во чисел, которые лежат справа и которые меньше его самого. Помогите пожалуйста как решать подобную задачу.
| № | Пользователь | Рейтинг |
|---|---|---|
| 1 | Benq | 3792 |
| 2 | VivaciousAubergine | 3647 |
| 3 | Kevin114514 | 3611 |
| 4 | jiangly | 3583 |
| 5 | strapple | 3515 |
| 6 | tourist | 3470 |
| 7 | Radewoosh | 3415 |
| 8 | Um_nik | 3376 |
| 9 | maroonrk | 3361 |
| 10 | XVIII | 3345 |
| Страны | Города | Организации | Всё → |
| № | Пользователь | Вклад |
|---|---|---|
| 1 | Qingyu | 162 |
| 2 | adamant | 148 |
| 3 | Um_nik | 146 |
| 4 | Dominater069 | 143 |
| 5 | errorgorn | 141 |
| 6 | cry | 138 |
| 7 | Proof_by_QED | 136 |
| 8 | YuukiS | 135 |
| 9 | chromate00 | 134 |
| 10 | soullless | 133 |
Дана довольно банальная задача. Дан массив состоящий из N чисел (N<=10^5). Нужно для каждого числа вывести кол-во чисел, которые лежат справа и которые меньше его самого. Помогите пожалуйста как решать подобную задачу.
| Название |
|---|



Строишь декатово дерево по явному ключу (с поддержкой размера поддеревьев), двигаясь справа на лево. Соответственно сплитишь по текущему ключу и смотришь, сколько элементов в левом дереве.
Используешь дерево отрезков. Если числа большие (<= 10 ^ 9), то сжимаешь координаты, потом идешь справа налево, и для каждого числа a[i] берешь сумму от 1 до a[i] — 1, и не забудь обновить дерево update (a[i], 1).
в деревьях не силен, к сожалению, но первое что пришло в голову() возможно не работает и не красиво , просьба не ругать, а лучше указать на ошибки а также более хорошее , оптимальное и правильное решение
Твое решение имеет сложность О(N^2). Для массива из 10^5 элементов, твое решение будет очень долго работать.
Предлагаю такой алгоритм: Идем по массиву с конца одновременно запихивая числа в multiset, до запихивания очередного числа проверяем сколько в multiset'е чисел меньше текущего, запоминаем ответы.
O (n log n).
Вот только не помню как узнать сколько в multiset чисел меньших какого-то за O(log n).
А с помощью multiset за O(log n) узнать нельзя.
Поэтому я и сказал сверху, что можно юзать декартово дерево, а меня почему-то минусят =(
UPD. А вообще можно любое бинарное дерево поиска использоавать, просто на мой взгляд декартово писать проще всего
Возможно потому, что дерево Фенвика куда проще.
Расскажи, как решать это задачу деревом фенвика?
http://mirror.codeforces.com/blog/entry/8256#comment-139517 . только вместо дерева отрезков дерево Фенвика использовать
Ну там идея немного другая.
Я извиняюсь, но можете рассказать немного другую идею?...я только такую знаю....
Нет, идея и там и там абсолютно одинаковая. Только для дерева отрезком или Фенвика надо сжимать координаты (т.е. так как для числа важен только относительный порядок, а не абсолютное значение, то можно их все кинуть в массив, отсортировать и заменить на индекс в массиве). Для декартова дерева это не требуется. Однако, если числа будут заране неизвестны, а поступать в режиме online, то необходимо будет или декартово дерево или явное дерево отрезков в котором поддеревья с нулем элементов выгружаются из памяти.
Да абсолютно всё, что угодно в этой задаче проще, чем декартово дерево.
Расскажи, в какой вселенной декартово дерево — самое простое из бинарных деревьев?
Ну пишется уж точно короче, чем остальные деревья поиска.
Декартово дерево
Дерево Фенвика
Дерево отрезков
Дерево Фенвика и отрезков деревьями поиска не являются.
Эта задача аналогична подсчету числа инверсий в массиве, только здесь мы считаем инверсии для каждого элемента, поэтому наравне с использованием различных деревьев можно использовать модификацию сортировки слияния по убыванию массива пар <элемент, индекс в изначальном массиве> (индекс нужен для восстановления ответа).
Модификация известная и состоит в следующем: когда мы сравниваем текущие элементы левого и правого массивов left[i] и right[j], то при left[i] > right[j] все дальнейшие элементы правого массива также меньше (мы сортируем по убыванию), поэтому мы прибавляем к ответу для left[i] число (right.length — j + 1).
Если за O(n logn) устроит, то так:
UPD: это неправильно, ошибся с std::distance.
У
multisetне random-access итераторы —distanceбудет за линию работать в худшем.