티스토리 뷰
전에 공장 문제에서 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 + 1, 0), l(n + 1, 0), r(n + 1, 0),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 |
댓글