Перестановкой назовем массив, состоящий из n различных целых чисел от 0 до n − 1 в произвольном порядке. Например, [ 2 , 1 , 0 , 4 , 3 ] является перестановкой, а [ 0 , 1 , 1 ] и [ 0 , 2 ] — нет. На день рождения Пете подарили перестановку p 1 , p 2 , … , p n . Счастье Пети определяется как количество пар ( i , j ) , таких что 1 ≤ i < j ≤ n и p i > p j . Пете разрешено многократно выполнять следующую операцию: переместить первый элемент перестановки в ее конец. Например, если изначально у Пети была перестановка [ 1 , 2 , 0 , 4 , 3 ] , то после применения операции у него будет перестановка [ 2 , 0 , 4 , 3 , 1 ] . Для каждого k от 0 до n − 1 выведите значение счастья Пети, если он выполнит данную операцию k раз. Формат входных данных Первая строка содержит число n ( 2 ≤ n ≤ 3 ⋅ 10 5 ) — размер перестановки. Вторая строка содержит записанные через пробел числа p 1 , p 2 , … , p n — перестановку чисел от 0 до n − 1 . Формат выходных данных В следующих n строках выведите числа a 0 , a 1 , … , a n − 1 , где a k — счастье Пети при условии, что он k раз переместил первый элемент перестановки в ее конец.
Примеры
Входные данные
5
0 1 2 3 4
Выходные данные
0
4
6
6
4
Входные данные
10
0 8 1 2 7 4 5 3 6 9
Выходные данные
13
22
15
22
27
22
23
22
25
22
Входные данные
5
0 4 1 3 2
Выходные данные
4
8
4
6
4
C/C++
Нужна идея по этой задаче, идея в лоб считать не подходит. Код не нужен
Считаем "в лоб" счастье исходной перестановки: S[0].
Счастье перестановки S[k] считаем по рекуррентной формуле:
S[k] = S[k - 1] + N - 2 * A[k] - 1
Объяснение: Перенос первого элемента в конец массива уменьшает кол-во счастливых пар на A[0] (все элементы меньше A[0]) и одновременно увеличивает кол-во счастливых пар на (N - 1) - A[0] (все элементы больше A[0]).
Счастье перестановки S[k] считаем по рекуррентной формуле:
S[k] = S[k - 1] + N - 2 * A[k] - 1
Объяснение: Перенос первого элемента в конец массива уменьшает кол-во счастливых пар на A[0] (все элементы меньше A[0]) и одновременно увеличивает кол-во счастливых пар на (N - 1) - A[0] (все элементы больше A[0]).
Дмитрий Герасимов
S[k] - количество счастья после k операций, A[k] — k-й элемент массива, я правильно понял?
Дмитрий Герасимов
А можно ли посчитать s[0] быстрее чем за квадрат, а то тайм лимит выходит
Для решения данной задачи можно использовать следующий алгоритм:
- Создать массив cnt размера n и заполнить его нулями.
- Пройти по всем элементам перестановки и увеличить cnt[p[i]] на 1.
- Создать массив pref размера n и заполнить его нулями.
- Пройти по всем элементам массива cnt и вычислить значения pref[i] как сумму cnt[j] для всех j от 0 до i.
- Создать переменную ans и заполнить ее нулем.
- Пройти по всем элементам перестановки и для каждого элемента p[i] вычислить количество элементов, которые меньше p[i], используя массив pref.
- Добавить полученное значение к ans.
- Вывести ans.
- Повторить шаги с 2 по 8 k раз, перемещая первый элемент перестановки в ее конец.
#include
#include
using namespace std;
int main() {
int n;
cin >> n;
vector p(n);
for (int i = 0; i < n; i++) {
cin >> p[i];
}
vector cnt(n), pref(n);
for (int i = 0; i < n; i++) {
cnt[p[i]]++;
}
for (int i = 1; i < n; i++) {
pref[i] = pref[i - 1] + cnt[i - 1];
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans += pref[p[i]];
}
cout
Похожие вопросы
- Нужна помощь при решении задачи в c++
- Программирование, нужна помощь в решение задачи! На си или си++
- Напишите пожалуйста код на 5 вариант очень простой я на 1 курсе вуза и нужен простой код.
- Можете подсказать по задаче или дать алгоритм задачи, код опять же не нужен
- Как оптимизировать код, чтобы не было превышения по времени к задаче (C++, динамическое программирование)?
- Как оптимизировать код, чтобы не было превышения по времени к задаче (C++)?
- Задача по c++ на векторы. Часть программы написана. Нужны правки.
- Написать код для задачи C++
- Помогите с кодом задачи c++. задача на фото
- Нужна помощь с написанием кода на языке "С"