Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Тема: корнячка❤️❤️❤️❤️❤️ на с++

Кирилл Стрикель Профи (756), на голосовании 2 месяца назад
В общем, есть задача, дан массив целых чисел и нужно, для каждого запроса надо отвечать сколько различных чисел на подмассиве, допустим для массива 1 2 1 3 2, для запроса 2 5 - ответ 3(3 различных числа), проблема вот в чём, все числа массива до 1000000000, более формально задаются вопросы так:
На первой строке длина массива n < 300000
Потом сам массив
Кол-во запросов q < 300000
сами запросы по два числа(границы)
Вот мой код:
 #include  
using namespace std;

struct Query {
int l, r, index;
};

bool compare(const Query &a, const Query &b, int block_size) {
if (a.l / block_size == b.l / block_size) {
return (a.l / block_size) % 2 == 0 ? a.r < b.r : a.r > b.r;
}
return a.l < b.l;
}

void add(int x, vector &count, int ¤t_answer) {
if (count[x] == 0) {
current_answer++;
}
count[x]++;
}

void remove(int x, vector &count, int ¤t_answer) {
if (count[x] == 1) {
current_answer--;
}
count[x]--;
}

int main() {
ios::sync_with_stdio(0);
cin.tie(0);

int n;
cin >> n;

vector arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int q;
cin >> q;
vector queries(q);
for (int i = 0; i < q; i++) {
cin >> queries[i].l >> queries[i].r;
queries[i].l--; // переводим в 0-индексацию
queries[i].r--;
queries[i].index = i;
}
int MAX_VALUE = *max_element(arr.begin(), arr.end());
// Создаем вектор для хранения количества вхождений чисел
vector count(MAX_VALUE + 1, 0);
int block_size = sqrt(n);
sort(queries.begin(), queries.end(), [&block_size](Query &a, Query &b) {
return compare(a, b, block_size);
});
vector answers(q);
int current_answer = 0;
int current_l = 0, current_r = -1;
for (const auto &query : queries) {
while (current_r < query.r)
add(arr[++current_r], count, current_answer);
while (current_r > query.r)
remove(arr[current_r--], count, current_answer);
while (current_l < query.l)
remove(arr[current_l++], count, current_answer);
while (current_l > query.l)
add(arr[--current_l], count, current_answer);

answers[query.index] = current_answer;
}
for (int i = 0; i < q; i++) {
cout << answers[i] << "\n";
}
return 0;
}
В нём я применяю алгоритм-МО(обрабатываю запросы в оффлайне)
У него бывает переполнение, когда максимальное, число большое(например, 1e9)
Если код писать с unordered_map, то код будет работать долго
Помогите, пожалуйста!
Голосование за лучший ответ
Resurce InheiT Профи (928) 3 месяца назад
Слишком много кода. Не оптимизирован. Замени vector<int> count(MAX_VALUE + 1, 0); на unordered_map<int, int> count;. Переполнение стека - твоя проблема.
Кирилл СтрикельПрофи (756) 3 месяца назад
a) я не вижу строчки stack<int>.
б) я написал, что unordered_map<int, int> count; - это долго.
в) я написал сюда, чтобы мне помогли, а не с явным пафосом сказали, что мой код работает долго.
г) что значит много кода, если для тебя 60 строк кода, это прям так много, то у меня к тебе большие вопросы.
Николай Веселуха Высший разум (368878) Кирилл Стрикель, а где ссылка на саму задачу в LeetCode?
Николай ВеселухаВысший разум (368878) 3 месяца назад
Да и 1 МБ в консоль в цикле будет выводиться медленно. stringstream эту проблему решает легко.
Похожие вопросы