Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <unordered_map>
- template<typename T>
- class SegmentTree {
- private:
- int CAPACITY_;
- T* array_;
- T (* merge_function_)(T, T);
- T default_value_;
- public:
- SegmentTree(int capacity, T* array, T (* merge_function)(T, T), T default_value)
- : merge_function_(merge_function), default_value_(default_value) {
- CAPACITY_ = 1;
- while (CAPACITY_ < capacity) {
- CAPACITY_ <<= 1;
- }
- initialize();
- for (size_t i = 0; i < capacity; ++i) {
- array_[CAPACITY_ + i] = array[i];
- }
- build();
- }
- T query(int l, int r) {
- return query_(std::max(0, l), std::min(r, CAPACITY_ - 1), 0, CAPACITY_ - 1, 1);
- }
- void update(int i, T value) {
- if (i >= CAPACITY_) {
- return;
- }
- array_[CAPACITY_ + i] = value;
- update_(CAPACITY_ + i);
- }
- private:
- void initialize() {
- array_ = new T[2 * CAPACITY_];
- for (int i = 2 * CAPACITY_ - 1; i >= 0; --i) {
- array_[i] = default_value_;
- }
- }
- void build() {
- for (int i = CAPACITY_ - 1; i > 0; --i) {
- array_[i] = merge_function_(array_[2 * i], array_[2 * i + 1]);
- }
- }
- T query_(int l, int r, int left, int right, int vertex) {
- if (r < l) {
- return default_value_;
- }
- if (l == left && r == right) {
- return array_[vertex];
- }
- int middle = (left + right) >> 1;
- return merge_function_(
- query_(l, std::min(middle, r), left, middle, vertex * 2),
- query_(std::max(l, middle + 1), r, middle + 1, right, vertex * 2 + 1)
- );
- }
- void update_(int i) {
- while (i > 1) {
- i >>= 1;
- array_[i] = merge_function_(array_[2 * i], array_[2 * i + 1]);
- }
- }
- };
- long long merge_sum(long long a, long long b) {
- return a + b;
- }
- int main() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- std::freopen("input.txt", "r", stdin);
- std::freopen("output.txt", "w", stdout);
- int n;
- std::cin >> n;
- std::vector<std::pair<int, int>> stars(n);
- std::unordered_map<int, int> index_of_first_level_star;
- int max_x = -1;
- for (int i = 0; i < n; ++i) {
- std::cin >> stars[i].first >> stars[i].second;
- if (index_of_first_level_star.count(stars[i].second) == 0) {
- index_of_first_level_star[stars[i].second] = i;
- }
- max_x = std::max(stars[i].first, max_x);
- }
- std::vector<long long> count(max_x + 1, 0);
- SegmentTree<long long> tree(count.size(), count.data(), &merge_sum, 0);
- std::unordered_map<long long, int> answer;
- std::vector<long long> answer_for_star(stars.size());
- answer[0] = 1;
- answer_for_star[0] = 0;
- tree.update(stars[0].first, 1);
- for (int i = 1; i < stars.size(); ++i) {
- if (stars[i].second == stars[i - 1].second) {
- answer_for_star[i] = answer_for_star[i - 1] + 1 + tree.query(stars[i - 1].first + 1, stars[i].first);
- } else if (stars[i].first == stars[i - 1].first) {
- answer_for_star[i] = answer_for_star[i - 1] + 1;
- } else if (stars[i].first < stars[i - 1].first) {
- answer_for_star[i] = answer_for_star[i - 1] + 1 - tree.query(stars[i].first + 1, stars[i - 1].first);
- } else {
- answer_for_star[i] = answer_for_star[i - 1] + 1 + tree.query(stars[i - 1].first + 1, stars[i].first);
- }
- answer[answer_for_star[i]]++;
- tree.update(stars[i].first, tree.query(stars[i].first, stars[i].first) + 1);
- }
- for (int i = 0; i < n; ++i) {
- std::cout << answer[i] << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement