πŸ”₯ PS(Problem Solving) πŸ”₯/BOJ

[BOJ] #10868 μ΅œμ†Ÿκ°’

dar0m! 2021. 2. 15. 22:21
μ‹œκ°„ μ œν•œ λ©”λͺ¨λ¦¬ μ œν•œ μ •λ‹΅ λΉ„μœ¨
 1 초  256 MB 47.180%
 

10868번: μ΅œμ†Ÿκ°’

N(1 ≤ N ≤ 100,000)개의 μ •μˆ˜λ“€μ΄ μžˆμ„ λ•Œ, a번째 μ •μˆ˜λΆ€ν„° b번째 μ •μˆ˜κΉŒμ§€ μ€‘μ—μ„œ 제일 μž‘μ€ μ •μˆ˜λ₯Ό μ°ΎλŠ” 것은 μ–΄λ €μš΄ 일이 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100,000)개 μ£Όμ–΄μ‘Œμ„ λ•ŒλŠ”

www.acmicpc.net

 

문제

N(1 ≤ N ≤ 100,000)개의 μ •μˆ˜λ“€μ΄ μžˆμ„ λ•Œ, a번째 μ •μˆ˜λΆ€ν„° b번째 μ •μˆ˜κΉŒμ§€ μ€‘μ—μ„œ 제일 μž‘μ€ μ •μˆ˜λ₯Ό μ°ΎλŠ” 것은 μ–΄λ €μš΄ 일이 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100,000)개 μ£Όμ–΄μ‘Œμ„ λ•ŒλŠ” μ–΄λ €μš΄ λ¬Έμ œκ°€ λœλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•΄ 보자.

μ—¬κΈ°μ„œ aλ²ˆμ§ΈλΌλŠ” 것은 μž…λ ₯λ˜λŠ” μˆœμ„œλ‘œ aλ²ˆμ§ΈλΌλŠ” 이야기이닀. 예λ₯Ό λ“€μ–΄ a=1, b=3이라면 μž…λ ₯된 μˆœμ„œλŒ€λ‘œ 1번, 2번, 3번 μ •μˆ˜ μ€‘μ—μ„œ μ΅œμ†Ÿκ°’μ„ μ°Ύμ•„μ•Ό ν•œλ‹€. 각각의 μ •μˆ˜λ“€μ€ 1이상 1,000,000,000μ΄ν•˜μ˜ 값을 κ°–λŠ”λ‹€.

첫째 쀄에 N, M이 μ£Όμ–΄μ§„λ‹€. λ‹€μŒ N개의 μ€„μ—λŠ” N개의 μ •μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. λ‹€μŒ M개의 μ€„μ—λŠ” a, b의 쌍이 μ£Όμ–΄μ§„λ‹€.
M개의 쀄에 μž…λ ₯받은 μˆœμ„œλŒ€λ‘œ 각 a, b에 λŒ€ν•œ 닡을 좜λ ₯ν•œλ‹€.

 

ν•΄κ²°

key point, μ„Έκ·Έλ¨ΌνŠΈ 트리
  • μ„Έκ·Έλ¨ΌνŠΈ 트리λ₯Ό ꡬ성할 트리의 높이λ₯Ό κ΅¬ν•œλ‹€. → h
    • 리프 λ…Έλ“œμ— μž…λ ₯받은 수λ₯Ό μ°¨λ‘€λ‘œ 놓을 것이기 λ•Œλ¬Έμ— λ¦¬ν”„λ…Έλ“œμ˜ κ°œμˆ˜κ°€ n보닀 ν¬κ²Œλ” while문을 ν™œμš©ν•˜μ—¬ 높이λ₯Ό ꡬ해쀀닀.
    • 리프 λ…Έλ“œλ₯Ό μ œμ™Έν•œ λ…Έλ“œλŠ” κ΅¬κ°„μ˜ μ΅œμ†Ÿκ°’μ„ κ°–κ³  μžˆλŠ”λ‹€.
  • ν•΄λ‹Ή μ„Έκ·Έλ¨ΌνŠΈ νŠΈλ¦¬μ—μ„œλŠ” κ΅¬κ°„μ˜ μ΅œμ†Ÿκ°’μ„ ꡬ해야 ν•˜κΈ° λ•Œλ¬Έμ— INF λ¬΄ν•œλŒ€ κ°’μœΌλ‘œ μ΄ˆκΈ°ν™” ν•œλ‹€. → fill(seg.begin(), seg.end(), INF)
  • udpate ν•¨μˆ˜λŠ” i μœ„μΉ˜μ— num을 μ €μž₯ν•˜λŠ” 것이고, μ²˜μŒμ—” i + h둜 λ¦¬ν”„λ…Έλ“œμ— μ €μž₯μ‹œν‚¨ 후에 /= 2λ₯Ό ν•˜λ©° 쑰상 λ…Έλ“œλ‘œ μ˜¬λΌκ°€ κ΅¬κ°„μ˜ μ΅œμ†Ÿκ°’μ„ μ €μž₯ν•œλ‹€.
  • query ν•¨μˆ˜λŠ” κ΅¬κ°„μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” ν•¨μˆ˜λ‹€.
    • l, r은 찾고자 ν•˜λŠ” λ²”μœ„μ˜ μ‹œμž‘κ³Ό 끝이고, num은 ν˜„μž¬ 보고 μžˆλŠ” λ…Έλ“œ 번호, nl, nr은 ν˜„μž¬ 보고 μžˆλŠ” λ²”μœ„μ˜ μ‹œμž‘κ³Ό 끝이닀.
    • ꡬ간에 λ”°λΌμ„œ μ΅œμ†Ÿκ°’μ„ λ°˜ν™˜ν•˜κ±°λ‚˜, λ¬΄ν•œλŒ€κ°’μ„ λ°˜ν™˜ν•˜κ±°λ‚˜, μž¬κ·€ν•¨μˆ˜λ₯Ό 톡해 닡을 κ΅¬ν•œλ‹€.

 

μ½”λ“œ

λ©”λͺ¨λ¦¬ μ‹œκ°„
 3280 KB  112 ms
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
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long int ll;
#define INF 1e9
int n, m, h = 1;
vector<ll> seg;
void update(int i, int num) {
    i += h;
    seg[i] = num;
    while (i > 1) {
        i /= 2;
        seg[i] = min(seg[i * 2], seg[i * 2 + 1]);
    }
}
// l, r μ°ΎλŠ” λ²”μœ„, num ν˜„μž¬ λ…Έλ“œ λ²ˆν˜Έ, nl, nr ν˜„μž¬ λ²”μœ„
ll query(int l, int r, int num, int nl, int nr) {
    if (l <= nl && nr <= r) return seg[num];
    if (nl > r || nr < l) return INF;
 
    int mid = (nl + nr) / 2;
    return min(query(l, r, num * 2, nl, mid), query(l, r, num * 2 + 1, mid + 1, nr));
}
 
int main() {
    scanf("%d%d"&n, &m);
    while (h < n) h <<= 1;
    seg.resize(h * 2);
    fill(seg.begin(), seg.end(), INF);
    for (int i = 0, a; i < n; i++) {
        scanf("%d"&a);
        update(i, a);
    }
    for (int i = 0, a, b; i < m; i++) {
        scanf("%d%d"&a, &b);
        printf("%lld\n", query(a, b, 11, h));
    }
    return 0;
}
cs