티스토리 뷰

알고리즘/BOJ

[백준] 7578 공장

세진짱 2018. 5. 30. 14:24


교차하는 케이블의 수를 세는 문제다

펜윅트리 or 머지소트로 풀수있다..!

처음에 세그먼트트리로 풀었는데 계속 시간초과가 나길래

방법이 틀린 줄 알았는데 map을 써서 시간초과가 났따 ㅎㅎ


문제를 푸는 방법은


1. 펜윅트리를 만든다. 초기값은 모두 0

2. 1~n까지 탐색을하며 B에서의 나의 위치 뒤에있는 것의 합을 더한다!

3. 그리고 나의 위치를 트리에서 1로 바꿔준다


교차점의 수를 세는 것이므로 A의 앞에있던 공장이 B에서는 뒤에있다면 교차점이 생긴다. 그래서 뒤에 1이 몇개있는지만 세어주면 된다!


소스코드 - 펜윅트리

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
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n;
#define ll long long
int a[500050], tree[500050],mp[1000010];
 
int sum(int i) {
    int ret = 0;
    while (i > 0) {
        ret += tree[i];
        i -= (i&(-i));
    }
    return ret;
}
 
void update(int i) {
    while (i <= n) {
        tree[i] += 1;
        i += (i&(-i));
    }
}
 
int main() {
    scanf(" %d"&n);
 
    for (int i = 1; i <= n; i++scanf(" %d"&a[i]);
    for (int i = 1; i <= n; i++) {
        int x; scanf(" %d"&x);
        mp[x] = i;
    }
 
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += (ll)sum(n) - (ll)sum(mp[a[i]]);
        update(mp[a[i]]);
    }
    printf("%lld\n", ans);
}
cs

세그먼트트리
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
#define ll long long
int n;
int mp[1000100];
 
void update(vector<int>&tree, int node, int start, int endint index, int val) {
    if (index <start || index > endreturn;
    if (start == end) {
        tree[node] = val; return;
    }
    update(tree, node * 2, start, (start + end/ 2, index, val);
    update(tree, node * 2 + 1, (start + end/ 2 + 1end, index, val);
    tree[node] = tree[node * 2+ tree[node * 2 + 1];
}
 
int query(vector<int>&tree, int node, int start, int endint i, int j) {
    if (j<start || i>endreturn 0;
    if (i <= start && end <= j) return tree[node];
    return query(tree, node * 2, start, (start + end/ 2, i, j) + query(tree, node * 2 + 1, (start + end/ 2 + 1end, i, j);
}
 
int main() {
    scanf(" %d"&n);
    int h = (int)ceil(log2(n));
    int tree_size = (1 << (h + 1));
    vector<int> a(n);
    vector<int> tree(tree_size);
 
    for (int i = 0; i < n; i++scanf(" %d"&a[i]);
    for (int i = 0; i < n; i++) {
        int x; scanf(" %d"&x);
        mp[x] = i;
    }
 
    ll ans = 0;
    for (int i = 0; i < n; i++) {
        ans += (ll)query(tree, 10, n - 1, mp[a[i]], n - 1);
        update(tree, 10, n - 1, mp[a[i]], 1);
    }
    printf("%lld\n", ans);
}
cs
 cs


'알고리즘 > BOJ' 카테고리의 다른 글

[백준] 1948 임계경로  (0) 2018.06.05
[백준] 15587 Cow at Large (Gold)  (0) 2018.06.01
[백준] 15805 트리 나라 관광 가이드  (0) 2018.05.29
[백준] 15772 Segmentation  (0) 2018.05.29
[백준] 15803 PLAYERJINAH’S BOTTLEGROUNDS  (0) 2018.05.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함