https://www.acmicpc.net/problem/2912
N명의 난쟁이가 모자를 쓰고 줄을 서고 있습니다.
구간 l ~ r에 존재하는 모자의 색상의 갯수를 종류별로 파악하여 어떤 모자가 절반보다 많이 있다면 yes와 색의 번호를 출력합니다.
이 문제에 업데이트가 없으므로 오프라인 쿼리가 가능하며, 구간을 효율적으로 움직이기 위해 Mo's 알고리즘을 사용합니다.
먼저 구간을 sqrt(N)으로 나누어 l / sqrt(N)을 기준으로 오름차순 정렬합니다.
l의 구간이 같다면 r을 기준으로 오름차순 정렬합니다.
그 다음 정렬된 쿼리를 하나씩 처리합니다.
구간을 이동하면서 색에 대한 카운팅을 진행합니다.
해당 구간에 대한 카운팅이 끝났으면 어떤 색이 절반보다 많이 차지하는지 찾습니다. (없다면 -1입니다.)
그 다음 구간을 갱신합니다.
M개의 쿼리를 모두 처리한 다음 한꺼번에 출력합니다.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include <iostream>
#include <algorithm>
#include <cmath>
#define MAX 300001
#define MAXQ 10001
using namespace std;
typedef struct Point {
int l, r, idx;
}Point;
Point q[MAXQ];
int list[MAX], ans[MAXQ], cnt[MAXQ];
int N, C, M, sqrtN;
bool cmp(Point a, Point b) {
int x = a.l / sqrtN;
int y = b.l / sqrtN;
if (x == y) return a.r < b.r;
else return x < y;
}
void solve(int idx, int k) {
for (int i = 1; i <= C; i++) {
if (cnt[i] > k / 2) {
ans[idx] = i;
return;
}
}
ans[idx] = -1;
}
void func() {
int l = q[1].l;
int r = q[1].r;
for (int i = l; i <= r; i++) {
cnt[list[i]]++;
}
solve(q[1].idx, r - l + 1);
for (int i = 2; i <= M; i++) {
int nl = q[i].l;
int nr = q[i].r;
int idx = q[i].idx;
for (int j = l; j < nl; j++) {
cnt[list[j]]--;
}
for (int j = l - 1; j >= nl; j--) {
cnt[list[j]]++;
}
for (int j = r; j > nr; j--) {
cnt[list[j]]--;
}
for (int j = r + 1; j <= nr; j++) {
cnt[list[j]]++;
}
solve(idx, nr - nl + 1);
l = nl;
r = nr;
}
for (int i = 1; i <= M; i++) {
if (ans[i] == -1) cout << "no\n";
else cout << "yes " << ans[i] << '\n';
}
}
void input() {
cin >> N >> C;
for (int i = 1; i <= N; i++) {
cin >> list[i];
}
sqrtN = sqrt(N);
cin >> M;
for (int i = 1; i <= M; i++) {
cin >> q[i].l >> q[i].r;
q[i].idx = i;
}
sort(q + 1, q + 1 + M, cmp);
}
int main() {
cin.tie(NULL); cout.tie(NULL);
ios::sync_with_stdio(false);
input();
func();
return 0;
}
|
cs |
'algorithm > Mo's' 카테고리의 다른 글
boj 12999 화려한 마을3 (0) | 2022.09.07 |
---|