문제 링크
문제 출처
- ICPC > Regionals > North America > Pacific Northwest Regional > 2012 Pacific Northwest Region Programming Contest H번
사용 알고리즘
- 세그먼트 트리(Inversion Counting)
시간 복잡도
- O(NlogN)
풀이
서로 다른 순서로 앉은 쌍의 최솟값을 구하기 위해 Inversion Counting을 사용합니다.
입력이 String으로 들어오기 때문에, string과 인덱스를 받을 자료구조가 필요하므로 map을 사용합니다.
- std::map은 검색(find), 삽입(insert), 제거(erase) 작업을 log 시간에 수행할 수 있습니다.
전체 코드
#include<bits/stdc++.h>
using namespace std;
#define INF 1e9
#define ll long long
const int mxN=1e5+10;
int n;
vector<ll> arr, tree;
unordered_map<string, int> mp;
ll sum(int start, int end, int node, int left, int right) {
if(right < start || end < left) return 0;
if(left <= start && end <= right) return tree[node];
int mid = start + (end-start)/2;
return sum(start, mid, node*2, left, right) + sum(mid+1, end, node*2+1, left, right);
}
void update(int start, int end, int node, int index, int diff) {
if(index < start || end < index) return;
tree[node] += diff;
if(start == end) return;
int mid = start + (end-start)/2;
update(start, mid, node*2, index, diff);
update(mid+1, end, node*2+1, index, diff);
}
void Init() {
arr.clear();
tree.clear();
mp.clear();
}
int main() {
ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
while(1) {
cin >> n;
if(n==0) break;
arr.resize(n); tree.resize(4*n);
Init();
for(int i=0; i<n; i++) {
string s; cin >> s;
mp.insert({s, i});
}
for(int i=0; i<n; i++) {
string s; cin >> s;
auto it = mp.find(s);
arr[i] = it->second;
}
ll ans=0;
for(int i=0; i<n; i++) {
int now = arr[i];
ans += sum(0, n-1, 1, now+1, n-1);
update(0, n-1, 1, now, 1);
}
cout << ans << "\n";
}
}
728x90
반응형
'알고리즘' 카테고리의 다른 글
[BOJ/백준] 1162번 - 도로포장 (0) | 2023.02.04 |
---|---|
[BOJ/백준] 7453번 - 합이 0인 네 정수 (0) | 2023.02.04 |
[BOJ/백준] 14502번 - 연구소 C++ 문제 풀이(시간 초과 포함) (0) | 2021.10.03 |
동적 계획법(Dynamic Programming) (0) | 2021.09.13 |
다익스트라 알고리즘(Dijkstra's Algorithm) (0) | 2021.09.12 |