일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 세그먼트트리
- 에라토스테네스의 체
- 다익스트라
- 구현
- dfs
- 그리디
- 누적합
- 위상정렬
- lis
- MST
- 브루트포스
- 이분탐색
- 플로이드와샬
- boj
- 투포인터
- lca
- BFS
- DisjointSet
- LazyPropagation
- 펜윅트리
- 크루스칼
- 좌표압축
- 이분매칭
- 수학
- 비트마스크
- 정렬
- 삼분탐색
- 이진탐색
- 백준
- DP
Archives
- Today
- Total
lastknight00
[백준]오등큰수(17299) 본문
문제 링크 : [백준]오등큰수(17299)
문제 설명
N개의 수열이 주어졌을 때, 수열 전체에 임의의 숫자(v)가 나타난 횟수를 F(v)라고 할 때,
수열의 각 수 오른쪽에 있는 수 중 F(v)가 현재 위치의 F(v)보다 큰 수 중 가장 왼쪽에 있는 값들을 구하세요.
입력
N(수열의 크기, 1 <= N <= 1,000,000)
Ai(수열의 값)
7
1 1 2 3 4 2 1
출력
-1 -1 1 2 2 1 -1
카테고리
#스택
시간 복잡도 상한
O(NlogN)
해결 방법
- F(x)에 대한 값을 알아야 하기 때문에, 입력을 받으면서, 각 숫자가 몇 번씩 나오는지 카운팅합니다.
- 왼쪽부터 차례대로 보려면 기준 위치에서 오른쪽의 위치를 모두 살펴야 하기 때문에 O(N2)의 시간복잡도가 발생하게 됩니다.
- 오른쪽에서부터 거꾸로 살펴본다면??
- 오른쪽부터 훑게 되면, 특정 위치(x)보다 오른쪽에 있으면서, 그 위치의 F(d[x])의 값보다 작은 F(v)의 값은 필요가 없습니다.
- 예를들어, i가 3인 곳의 F(v)가 5, i가 4인 곳의 F(v)가 4라고 가정합니다.
- i가 2인 곳의 F(v)가 5보다 작다면, 3이 답이 될 것입니다.
- i가 2인 곳의 F(v)가 5보다 크거나 같다면, F(v)가 6 이상인 곳의 위치를 찾아야 합니다.
- 스택을 이용하여 자신의 F(v)보다 작은 값을을 계속 빼내서 스택을 오름차순으로 만들어 답을 구하면 됩니다.
시간복잡도
O(N)
코드
#include<iostream>
#define N 1000001
using namespace std;
int n,d[N],c[N],e[N],s[N],p,i;
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(;i<n;i++)cin>>d[i],c[d[i]]++;
for(i=n-1;i>-1;i--){
while(p&&c[d[i]]>=c[d[s[p-1]]])p--;
e[i]=p?d[s[p-1]]:-1;
s[p++]=i;
}
for(i=0;i<n;i++)cout<<e[i]<<" ";
}
'PS' 카테고리의 다른 글
[백준]숨바꼭질 5(17071) (0) | 2020.10.31 |
---|---|
[백준]철로(13334) (0) | 2020.10.31 |
[백준]특정한 최단 경로(1504) (0) | 2020.10.29 |
[백준]The Other Way(14554) (0) | 2020.10.29 |
[백준]물대기(1368) (0) | 2020.10.24 |
Comments