일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 이진탐색
- 투포인터
- 플로이드와샬
- 백준
- 수학
- 이분탐색
- LazyPropagation
- 이분매칭
- 삼분탐색
- lca
- 정렬
- 에라토스테네스의 체
- 누적합
- DisjointSet
- dfs
- 좌표압축
- 펜윅트리
- DP
- 크루스칼
- 다익스트라
- 비트마스크
- 세그먼트트리
- 위상정렬
- BFS
- MST
- 구현
- 브루트포스
- 그리디
- boj
- lis
Archives
- Today
- Total
lastknight00
[백준] 공장(7578) 본문
문제 링크 : [백준] 공장(7578)
문제 설명
두 개의 라인(위, 아래)이 있고, 위 라인과 아래 라인에 서로 짝이 이어지는 장비들이 N개 존재합니다.
짝을 이루는 장비는 서로 같은 번호를 가집니다.
짝을 이루는 장비들을 서로 연결하였을 때, 교차하는 지점의 갯수를 구하세요.
입력
N(장비의 갯수, 1<=N<=500,000)
Ui(윗 라인의 장비 배치, 0<=Ui<=1,000,000)
Di(아래 라인의 장비 배치, 0<=Di<=1,000,000)
5
132 392 311 351 231
392 351 132 311 231
출력
3
카테고리
#펜윅트리, #세그먼트트리
시간 복잡도 상한
O(NlogN)까지 가능합니다.
해결 방법
- 한 장비를 연결하는데 몇 개의 선을 가로지르는지를 파악해야합니다.
- 위 라인에서는 장비i보다 왼쪽에 있었으나, 아래 라인에서 장비i보다 오른쪽에 있는 경우, 장비i와 교차하게 됩니다.
- 2에 의해서, 위 라인의 장비를 왼쪽에서 오른쪽 방향으로 검사한다면, 장비i와 교체하는 장비는 아래와 같은 조건의 장비들입니다.
3-1. 위 라인에서는 장비i보다 먼저 나타났지만
3-2. 아래 라인에서 장비i보다 오른쪽에 있는 장비 - 위 라인을 기준으로, 왼쪽에서 오른쪽으로 진행하면서, 3의 기준에 맞는 장비의 갯수를 세기 위해서는 아래와 같이 진행합니다.
4-1. 장비i의 아래 라인의 위치 ~ 끝까지 이미 나타난 장비의 갯수를 세어줌
4-2. 장비i의 아래 라인의 위치에 현재 장비가 나타났다는 표시를 해줌 - 특정 인덱스의 값을 변경, 구간의 합을 반복적으로 구해주는 로직이므로 펜윅 트리나, 세그먼트 트리를 이용하면 빠르게 구할 수 있습니다.
- 주의) 각 장비의 번호를 인덱스로만 주었으면 좀 간단했을텐데, 임의의 숫자로 주어 장비의 번호를 새로 인덱싱해야 합니다.
시간복잡도
O(NlogN)
코드
#include<iostream>
#define f for(i=1;i<=n;i++)
using namespace std;
int n,a[500001],b[1000001],c[500001],t,i;
long long s;
void u(int p){
while(p<=n)c[p]+=1,p+=p&-p;
}
int q(int p){
int r=0;
while(p)r+=c[p],p-=p&-p;
return r;
}
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
f cin>>a[i];
f cin>>t,b[t]=i;
f s+=q(n)-q(b[a[i]]),u(b[a[i]]);
printf("%lld",s);
}
'PS' 카테고리의 다른 글
[백준] 사탕상자(2243) (0) | 2020.05.29 |
---|---|
[백준] 커피숍2(1275) (0) | 2020.05.28 |
[백준] X와 K(1322) (0) | 2020.05.28 |
[백준] 트리의 높이와 너비(2250) (0) | 2020.05.27 |
[백준] 틱택토(7682) (0) | 2020.05.26 |
Comments