세그먼트 트리를 사용하는 문제이다.
이 문제에서는 "데이터 입력을 어떻게 처리하냐가" 중요한것 같다.
상당히 이해하기도 어려웠고 까다로웠던 문제였다.
굉장한 학생이란 3번의 모든 시험에서 학생 본인보다 대단한 학생이 없는 경우이다.
입력에서 1,2,3,5가 4명이 굉장한 학생이 된다.
#include <iostream> #include <algorithm> #include <vector> #include <string.h> #include <math.h> #include <queue> #include <set> #include <utility> #include <functional> #define MAX 500005 #define INF 987654321 #define MOD 1000000007 #pragma warning(disable:4996) using namespace std; typedef struct st { int first; int second; int third; }student; student arr[MAX]; int n, seg[4 * MAX], ans=0, tmp; bool cmp(student a, student b) { return a.first < b.first; } int update(int pos, int val, int cur, int left, int right) { if (right < pos || pos < left) return seg[cur]; if (left == right) return seg[cur] = val; int mid = (left + right)/2; return seg[cur] = min(update(pos, val, cur*2, left, mid), update(pos, val, cur*2+1, mid+1, right)); } int query(int dleft, int dright, int cur, int left, int right) { if (right < dleft || dright < left) return INF; if (dleft <= left&&right <= dright) return seg[cur]; int mid = (left + right)/2; return min(query(dleft,dright,cur*2,left,mid), query(dleft,dright,cur*2+1,mid+1,right)); } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &tmp); arr[tmp].first = i; } for (int i = 1; i <= n; i++) { scanf("%d", &tmp); arr[tmp].second = i; } for (int i = 1; i <= n; i++) { scanf("%d", &tmp); arr[tmp].third = i; } sort(arr + 1, arr + 1 + n, cmp); for (int i = 1; i <= n; i++) update(i, INF, 1, 1, n); for (int i = 1; i <= n; i++) { if (query(1, arr[i].second, 1, 1, n)>arr[i].third) ans++; update(arr[i].second, arr[i].third, 1, 1, n); } printf("%d\n", ans); return 0; }
'IT > BOJ' 카테고리의 다른 글
백준(BOJ) 5676 음주코딩 ** (0) | 2018.06.01 |
---|---|
백준(BOJ) 11505 구간 곱 구하기 * (0) | 2018.06.01 |
백준(BOJ) 1920 수찾기 * (0) | 2018.06.01 |
백준(BOJ) 10815 숫자 카드 * (0) | 2018.06.01 |
백준(BOJ) 7453 합이 0인 네 정수 * (0) | 2018.06.01 |