Дана довольно банальная задача. Дан массив состоящий из N чисел (N<=10^5). Нужно для каждого числа вывести кол-во чисел, которые лежат справа и которые меньше его самого. Помогите пожалуйста как решать подобную задачу.
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3993 |
2 | jiangly | 3743 |
3 | orzdevinwang | 3707 |
4 | Radewoosh | 3627 |
5 | jqdai0815 | 3620 |
6 | Benq | 3564 |
7 | Kevin114514 | 3443 |
8 | ksun48 | 3434 |
9 | Rewinding | 3397 |
10 | Um_nik | 3396 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 167 |
2 | Um_nik | 163 |
3 | maomao90 | 162 |
3 | atcoder_official | 162 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 156 |
8 | TheScrasse | 154 |
9 | Dominater069 | 153 |
10 | nor | 152 |
Дана довольно банальная задача. Дан массив состоящий из 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
будет за линию работать в худшем.