http://codeforces.com/contest/1131/problem/F
이거
풀이 맞는지좀 봐주셈
일단 유니온 파인드 사용하고(종만북에 구현된거 기준)
예제입력 푸는걸 예시로 들게
1.
일단 유니온파인드는 기본적으로 종만북에 나온것처럼 대표자 배열을 갖고 있음.
그리고 여기에 문제를 풀기위해 새로운 배열을 추가했는데, 초깃값은 자기 자신 하나밖에 담고있지 않는 배열임.
처음 생김새는
[ [1], [2], [3], [4], [5] ]
이렇게 생겼겠지
이걸 이제부터 '나의배열' 이라고 부를게
2.
예를들어서 예제입력에
1 4
가 들어왔다고 치면
둘중 하나를 다른족에 합쳐야 되는데
내경우는 일단 무조건 오른쪽애를 왼쪽에다가 합쳤음.
종만북에서는 rank를 유지하면서 rank가 큰애가 대표자되게 구현했는데
암튼 여기서는 예제입력이 1 4로 됬으면 무조건 4를 1에다가 합침
그래서
find(1)의 '나의배열' 에다가 find(4)의 '나의배열'을 합침.
그럼 나의배열은 이제 이렇게 되겠지
[ [1,4], [2], [3], [4], [5] ]
3.
이런식으로 문제의 예제입력을 처리한다면 '나의배열' 은 아래처럼 변해감
[ [1,4], [2], [3], [4], [5] ]
[ [1,4], [2,5], [3], [4], [5] ]
[ [1,4], [2,5], [3,1,4], [4], [5] ]
[ [1,4], [2,5], [3,1,4,2,5], [4], [5] ]
예제입력끝나고 '나의배열' 에서 제일긴놈을 정답으로 제출함 ( 여기서는 [3,1,4,2,5] )
저거 아이디어 맞음? 물론 N이 15만이라서 파이썬으로는 딱봐도 메모리터지긴 할텐데 C++로 풀어도 저방식 메모리 터짐?
그리고 메모리문제 말고도 '예제입력에서 x y 가 입력되는 순서는 실제 정답에서의 x와 y의 순서와 같다' 라고 가정하고있음. 실제로 위의 예제가 1 4 가 아니라 4 1 로 입력됬다면 또 어떻게 꼬일지 모른다는거임
암튼 이거 푸는방법 아이디어좀... 답지는 읽어봐도 모르겠어 ㅠㅠ
답지에 구현코드는 안나와있고 nlogN 이랑 na(a는 아커만함수) 두가지 방법이 있다는데 nlogN으로 푼다는방식은 읽어도 뭔말인지 모르겠음;;
아커만으로 걸린다는 방식 역시 유니온파인드를 쓴다는거 말고는 뭔말인지 모르겠음;; 해석 plz
이거 '엥? 웰노운아님?' 하면서 푸는애들 신기하다
작은거큰거라는 방법이 있음
저런 n개의 컴포넌트를 최종적으로 1개로 합칠 때 항상 작은걸 큰거에 합치면 총 시간복잡도가 O(nlgn)임이 증명되어있음
메모리 안터짐? '나의배열' 을 유지하는게 맞음? n이 15만이면 최악의경우 15만개 요소 하나하나가 15만개가 들어있는 배열을 갖게되는데. 내가 제일 걱정되는게 메모리떔에 물어본거임
동적배열 쓰면 메모리도 O(N)임
ㄳ
기본 아이디어는 맞고 왼쪽에 붙이든 오른쪽에 붙이든 그건 자유임 어차피 합치고 나면 그 다음 상태에서 합쳐진 모든 애들이 하나의 셀이기 때문에 어느 순서로 합치는지는 중요하지 않기 때문(그러니 입력이 1 4로 주어지든 4 1로 주어지든 잘 동작함). 위에서 말한 것처럼 합칠 때 사이즈가 작은 걸 큰 쪽에 붙여주는 방식으로만 하면 O(NlogN)에 풀림.
무조건 오른쪽을 왼쪽으로 합치지 말고 두 그룹 합칠 때 작은걸 큰 거에 합치셈. 그럼 최악의 경우가 그룹 크기가 같을 때 합치는 건데 이런 경우는 크기 무조건 2배씩 늘어나니 총 연산량 nlogn. 크기가 서로 다를 때는 오히려 연산량 줄어드니까 땡큐지
님들아 그럼 가장 중요한 '요소들의 순서' 를 기억하기 위해서는 위에서 말한 '나의배열' 아이디어가 맞나여? 최악의경우 15만 * 15만(또는 암튼 만단위) 의 메모리사용량이 되는데..
1. 맞음 2. 작은걸 큰거에 합치면 메모리 사용량도 O(NlgN)임. 합친 뒤에 작은걸 초기화시켜주면 O(N)도 가능할듯
그냥 했을 경우 1 2, 2 3, 3 4, ... 식으로 입력이 들어왔을 경우 시간 메모리 둘 다 O(N^2)나서 터지는 거고, 작은걸 큰거에 합치면 시간 메모리 둘 다 O(NlgN).
호오 오늘 많이배우네.. 메모리사용량도 NlgN 이라니.. 게다가 작은걸 초기화해준다는 아이디어까지
질문글 하나에 무수한 꿀팁의 요청이...!
같은 아이디어에 고양이도 나오는 문제
https://boj.kr/16858
내문제네 ㅋㅋ
vector 대신 list를 응용하면 합치는 연산을 O(1)에 처리해서 시간복잡도 O(Nα(N)) 메모리 O(N)이라는 듯 ㅇㅇ
ㄳ
그러고 보니 리스트 쓰면 편하네 ㅋㅋ PS 할 때 리스트를 아예 뇌 속에서 지워버려서 생각을 못했네