일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- DisjointSet
- 다익스트라
- 이분탐색
- BFS
- dfs
- 이진탐색
- boj
- 플로이드와샬
- LazyPropagation
- lis
- 누적합
- DP
- 에라토스테네스의 체
- 좌표압축
- 위상정렬
- 투포인터
- 삼분탐색
- 백준
- 수학
- 펜윅트리
- 브루트포스
- 그리디
- 정렬
- 세그먼트트리
- lca
- 구현
- 비트마스크
- MST
- 이분매칭
- 크루스칼
Archives
- Today
- Total
lastknight00
[백준] 순열복원(1777) 본문
문제 링크 : [백준] 순열복원(1777)
문제 설명
1부터 n까지의 수로 이루어진 순열이 있을 때, i보다 오른쪽에 있는 숫자 중 i 보다 작은 원소의 갯수들이 주어집니다.
예시
원래 순열 : 2 4 5 1 7 6 3 8
주어지는 수 : 0 1 0 2 2 1 2 0
7(5번째 원소)보다 오른쪽에 있으면서 7보다 작은 수는 두 개(6, 3)이기 때문에 2가 주어집니다.
위와 같은 값들이 주어졌을 때, 원래 순열을 구하십시요.
입력
N(순열의 크기, 1<=N<=100,000)
Di(i보다 오른쪽에 있는 수 중에서 Di보다 작은 수의 갯 수)
8
0 1 0 2 2 1 2 0
출력
원래 순열
2 4 5 1 7 6 3 8
카테고리
#펜윅트리, #세그먼트트리, #이분탐색
시간 복잡도 상한
O(NlogN)까지 가능합니다.
해결 방법
- i보다 오른쪽에 있으면서 i보다 작은 수의 갯수는 주어진 데이터를 보면 알 수 있습니다.
시간복잡도
O(N(logN)2)
코드
#include<cstdio>
int n,i,d[100001],t[400000],l,r,m,v,a[100001];
int u(int p,int l,int r,int i){
if(i>r||i<l)return t[p];
if(l==r)return t[p]^=1;
return t[p]=u(p*2,l,(l+r)/2,i)+u(p*2+1,(l+r)/2+1,r,i);
}
int q(int p,int l,int r,int x,int y){
if(y<l||x>r)return 0;
if(x<=l&&r<=y)return t[p];
return q(p*2,l,(l+r)/2,x,y)+q(p*2+1,(l+r)/2+1,r,x,y);
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",d+i),u(1,1,n,i);
for(i=n;i;i--){
l=1;r=n;
while(l<=r){
m=(l+r)/2;
v=q(1,1,n,m,n)-1;
if(v>d[i])l=m+1;
else r=m-1;
}
a[l]=i;
u(1,1,n,r);
}
for(i=1;i<=n;i++)printf("%d ",a[i]);
}
'PS' 카테고리의 다른 글
[백준] 행렬 곱셈 순서(11049) (0) | 2020.06.01 |
---|---|
[백준] 외판원 순회(2098) (0) | 2020.05.31 |
[백준] 북서풍(5419) (0) | 2020.05.31 |
[백준] 영화수집(3653) (0) | 2020.05.31 |
[백준] 사탕상자(2243) (0) | 2020.05.29 |
Comments