티스토리 뷰

알고리즘/BOJ

[백준] 5012 불만정렬

세진짱 2018. 6. 22. 21:20


전에 공장 문제에서 i<j 일때 arr[i]>arr[j]인 수를 찾는 것을 했다.

이 문제는 i<j<k && arr[i] > arr[j] > arr[k] 이므로 j를 기준으로

1. i<j && arr[i] > arr[j]

2. j<k && arr[j] < arr[k] 

두 개를 찾아서 곱하면 경우의 수가 나온다


1번을 역으로하면 2번을 바로 구할 수 있다


소스코드

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
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
#define MAXN 100010
int n;
int _sum(vector<int>&arr, int x) {
    int ret = 0;
    for (int i = x; i > 0; i -= (i&-i)) ret += arr[i];
    return ret;
}
int sum(vector<int>&arr, int s, int e) {
    return _sum(arr, e) - _sum(arr, s - 1);
}
void update(vector<int>&arr, int x, int val) {
    for (int i = x; i <= n; i += (i&-i)) arr[i] += val;
}
 
int main() {
    scanf(" %d"&n);
    vector<int>arr(n + 10), l(n + 10), r(n + 10),tree(n+1,0);
    for (int i = 1; i <= n; i++scanf(" %d"&arr[i]);
    for (int i = 1; i <= n; i++) {
        l[i] = sum(tree, arr[i] + 1, n);
        update(tree, arr[i], 1);
    }
    fill(tree.begin(), tree.end(), 0);
    for (int i = n; i >= 1; i--) {
        r[i] = sum(tree, 1, arr[i] - 1);
        update(tree, arr[i], 1);
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++) ans += (ll)r[i] * l[i];
    printf("%lld\n", ans);
}
cs


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

[백준] 1280 나무심기  (0) 2018.06.24
[백준] 9426 중앙값 측정  (0) 2018.06.22
[백준] 12016 라운드 로빈 스케줄러  (0) 2018.06.22
[백준] 11658 구간 합 구하기 3  (0) 2018.06.19
[백준] 9466 텀 프로젝트  (0) 2018.06.18
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
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
글 보관함