ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [2517] 달리기
    BOJ 2021. 10. 14. 05:47

    https://www.acmicpc.net/problem/2517

     

    2517번: 달리기

    첫째 줄에는 선수의 수를 의미하는 정수 N이 주어진다. N은 3 이상 500,000 이하이다. 이후 N개의 줄에는 정수가 한 줄에 하나씩 주어진다. 이 값들은 각 선수들의 평소 실력을 앞에서 달리고 있는

    www.acmicpc.net

    <문제>

    N에 비해 평소 실력의 범위가 매우 크다. 다만 필요한건 항상 대소관계 뿐이므로, 최대 50만으로 압축해줄 수 있다.

    세그먼트 트리를 이용하여 알고싶은건 나보다 평소실력이 낮은 사람의 수이다.

    자료구조를 만들고 쿼리의 리턴을 현재 등수(i)에서 빼주면 최고등수가 나온다. 

     

    <소스코드>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #include <bits/stdc++.h>
    using namespace std;
    vector<pair<intint>> a;
    vector<int> segTree;
    int n;
    bool cmp1(pair<intint> a, pair<intint> b) { return a.second < b.second; }
    bool cmp2(pair<intint> a, pair<intint> b) { return a.first < b.first; }
    int query(int i, int s, int e, int l, int r) {
        if (s > r || e < l) return 0;
        if (l <= s && e <= r) return segTree[i];
        int mid = (s + e) / 2;
        return query(2 * i, s, mid, l, r) + query(2 * i + 1, mid + 1, e, l, r);
    }
    void updateSegTree(int i, int s, int e, int idx) {
        if (s > idx || e < idx) return;
        segTree[i]++;
        if (s == e) return;
        int mid = (s + e) / 2;
        updateSegTree(2 * i, s, mid, idx);
        updateSegTree(2 * i + 1, mid + 1, e, idx);
    }
    int main(void) {
        int i;
        cin >> n;
        a.resize(n);
        for (i = 0; i < n; i++) {
            int x;
            cin >> x;
            a[i] = {i, x};
        }
        sort(a.begin(), a.end(), cmp1);
        for (i = 0; i < n; i++) {
            a[i].second = i;
        }
        sort(a.begin(), a.end(), cmp2);
        segTree.resize(4 * n);
        for (i = 0; i < n; i++) {
            int ans = query(10, n - 10, a[i].second);
            cout << i - ans + 1 << '\n';
            updateSegTree(10, n - 1, a[i].second);
        }
        return 0;
    }
    cs

     

    'BOJ' 카테고리의 다른 글

    [10973] 이전 순열  (0) 2021.10.14
    [16234] 인구 이동  (0) 2021.10.14
    [3055] 탈출  (0) 2021.10.13
    [9376] 탈옥  (0) 2021.10.13
    [2631] 줄세우기  (0) 2021.10.12

    댓글