# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
585881 | Mystic03 | Mountains (NOI20_mountains) | C++17 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define int long long
struct segmentTree {
int n;
vector<int> st;
segmentTree(int n) {
int x = (int)(ceil(log2(n)));
int max_size = 2 * (int)pow(2, x) - 1;
this->n = n;
st.resize(max_size, 0);
}
void build(int startRange, int endRange, int currNode, vector<int> const& v) {
if (startRange == endRange) {
st[currNode] = v[startRange];
return;
}
int mid = (startRange + endRange) / 2;
build(startRange, mid, currNode * 2 + 1, v);
build(mid + 1, endRange, currNode * 2 + 2, v);
st[currNode] = st[currNode * 2 + 1] + st[currNode * 2 + 2];
}
void build(vector<int>const& v) {
build(0, n - 1, 0, v);
}
int query(int startRange, int endRange, int l, int r, int currNode) {
if (endRange < l || startRange > r) return 0;
if (startRange >= l && endRange <= r) return st[currNode];
int mid = (startRange + endRange) / 2;
return (query(startRange, mid, l, r, currNode * 2 + 1) + query(mid + 1, endRange, l, r, currNode * 2 + 2));
}
int query(int l, int r) {
return query(0, n - 1, l, r, 0);
}
void update(int startRange, int endRange, int currNode, int index, int val) {
if (startRange == endRange) {
st[currNode] = val;
return;
}
int mid = (startRange + endRange) / 2;
if (index <= mid) {
update(startRange, mid, currNode * 2 + 1, index, val);
}
else {
update(mid + 1, endRange, currNode * 2 + 2, index, val);
}
st[currNode] = st[currNode * 2 + 1] + st[currNode * 2 + 2];
}
void update(int index, int val) {
update(0, n - 1, 0, index, val);
}
};
int main() {
int n;
cin >> n;
vector<pair<int,int>> v(n);
vector<int> elements(n,0);
for (int i = 0; i < n; i++) {
int x;
cin >> x;
v[i] = { x,i };
elements.push_back(x);
}
sort(v.begin(), v.end());
segmentTree tr(n);
tr.build(elements);
vector<int> index;
int cnt = 0;
tr.update(v[0].second, 1);
for (int i = 1; i < n; i++) {
index.push_back(v[i].second);
if(v[i].first != v[i - 1].first) {
for(int x : index){
tr.update(x, 1);
}
index.clear();
}
cnt += tr.query(0, v[i].second - 1) * tr.query(v[i].second + 1, n - 1);
}
cout << cnt << endl;
}