# 백설공주와 난쟁이

Created
2021/03/23 01:58
문제 번호
2912
카테고리
자료구조
세그먼트트리
Mo's

### Code

@1/5/2021

10240 KB

#### 시간

312 ms
#include <algorithm> #include <cmath> #include <iostream> #include <string> #include <vector> using pii = std::pair<int, int>; int g_no_dwarf; int g_no_color; int g_no_picture; std::vector<int> g_hat; std::vector<std::vector<int>> g_idx_cnt; std::vector<int> g_segment; std::vector<pii> g_ran; std::vector<std::string> g_ans; void pre_setting(void) { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL); } void input_action(void) { int i; int seg_size; std::cin >> g_no_dwarf >> g_no_color; seg_size = static_cast<int>(ceil(log2(g_no_dwarf))); g_hat = std::vector<int>(g_no_dwarf, 0); g_idx_cnt = std::vector<std::vector<int>>(g_no_color); g_segment = std::vector<int>((1 << (seg_size + 1)), -1); i = -1; while (++i < g_no_dwarf) { std::cin >> g_hat[i]; g_idx_cnt[g_hat[i] - 1].push_back(i); } std::cin >> g_no_picture; g_ran = std::vector<pii>(g_no_picture, std::make_pair(0, 0)); g_ans.reserve(g_no_picture); i = -1; while (++i < g_no_picture) std::cin >> g_ran[i].first >> g_ran[i].second; } int count_hat(int n, int s, int e) { int lower; int upper; upper = std::upper_bound(g_idx_cnt[n - 1].begin(), g_idx_cnt[n - 1].end(), e) - g_idx_cnt[n - 1].begin(); lower = std::lower_bound(g_idx_cnt[n - 1].begin(), g_idx_cnt[n - 1].end(), s) - g_idx_cnt[n - 1].begin(); return (upper - lower); } void update_tree(int n, int s, int e, int i, int val) { int l_child; int r_child; l_child = -1; r_child = -1; if (i < s || e < i) return ; if (s == e) { g_segment[n] = val; return ; } update_tree(n * 2 + 1, s, (s + e) / 2, i, val); update_tree(n * 2 + 2, (s + e) / 2 + 1, e, i, val); l_child = g_segment[n * 2 + 1]; r_child = g_segment[n * 2 + 2]; if (l_child != -1 && r_child != -1) { if (count_hat(l_child, s, e) > (e - s + 1) / 2) g_segment[n] = l_child; else if (count_hat(r_child, s, e) > (e - s + 1) / 2) g_segment[n] = r_child; else g_segment[n] = -1; } else if (l_child != -1 && r_child == -1) { if (count_hat(l_child, s, e) > (e - s + 1) / 2) g_segment[n] = l_child; else g_segment[n] = -1; } else if (l_child == -1 && r_child != -1) { if (count_hat(r_child, s, e) > (e - s + 1) / 2) g_segment[n] = r_child; else g_segment[n] = -1; } else g_segment[n] = -1; } int make_answer(int n, int s, int e, int l, int r) { int l_child; int r_child; l_child = -1; r_child = -1; if (s > r || e < l) return (-1); if (l <= s && e <= r) return (g_segment[n]); l_child = make_answer(n * 2 + 1, s, (s + e) / 2, l, r); r_child = make_answer(n * 2 + 2, (s + e) / 2 + 1, e, l, r); if (l_child != -1 && r_child != -1) { if (count_hat(l_child, l, r) > (r - l + 1) / 2) return (l_child); else if (count_hat(r_child, l, r) > (r - l + 1) / 2) return (r_child); return (-1); } else if (l_child != -1 && r_child == -1) { if (count_hat(l_child, l, r) > (r - l + 1) / 2) return (l_child); return (-1); } else if (l_child == -1 && r_child != -1) { if (count_hat(r_child, l, r) > (r - l + 1) / 2) return (r_child); return (-1); } return (-1); } void logic() { int i; int x; i = -1; while (++i < g_no_dwarf) update_tree(0, 0, g_no_dwarf - 1, i, g_hat[i]); i = -1; while (++i < g_no_picture) { x = make_answer(0, 0, g_no_dwarf - 1, g_ran[i].first - 1, g_ran[i].second - 1); if (x == -1) g_ans.push_back("no"); else g_ans.push_back("yes " + std::to_string(x)); } } void output_action(void) { int i; i = -1; while (++i < g_no_picture) std::cout << g_ans[i] << '\n'; } void solution(void) { input_action(); logic(); output_action(); } int main(void) { pre_setting(); solution(); return (0); }
C++