#include <bits/stdc++.h>
using namespace std;
/*
QUESTION IN SIMPLE WORDS
------------------------
For every array element a[i], find the farthest position to the right
where the value is smaller than a[i].
This version returns:
answer[i] = j - i (distance)
If you want the actual index j,
change the marked line below.
------------------------------------------------------------
BRUTE FORCE IDEA
------------------------------------------------------------
For every i:
- check every j > i
- if a[j] < a[i], keep the farthest such j
------------------------------------------------------------
WHY BRUTE FORCE IS TOO SLOW
------------------------------------------------------------
That takes O(n^2), which is too slow for large arrays.
------------------------------------------------------------
OPTIMIZED IDEA
------------------------------------------------------------
Process from right to left.
Why right to left?
Because when we are at index i,
all indices to the right have already been seen.
We use:
- coordinate compression
- Fenwick tree
Fenwick tree stores:
for each compressed value, the maximum index seen so far.
Then for a[i], we ask:
among all strictly smaller values, what is the largest index?
That gives the rightmost smaller element.
*/
struct FenwickMax {
int n;
vector<int> bit;
FenwickMax(int n = 0) { init(n); }
void init(int n_) {
n = n_;
bit.assign(n + 1, -1);
}
void update(int idx, int val) {
for (; idx <= n; idx += idx & -idx) {
bit[idx] = max(bit[idx], val);
}
}
int query(int idx) {
int ans = -1;
for (; idx > 0; idx -= idx & -idx) {
ans = max(ans, bit[idx]);
}
return ans;
}
};
vector<int> rightmostSmallerDistance(const vector<int>& a) {
int n = (int)a.size();
// Step 1: coordinate compression
vector<int> vals = a;
sort(vals.begin(), vals.end());
vals.erase(unique(vals.begin(), vals.end()), vals.end());
FenwickMax fw((int)vals.size());
vector<int> ans(n, 0);
// Step 2: process from right to left
for (int i = n - 1; i >= 0; i--) {
int id = lower_bound(vals.begin(), vals.end(), a[i]) - vals.begin() + 1;
// Query all strictly smaller values
int j = fw.query(id - 1);
if (j == -1) ans[i] = 0;
else ans[i] = j - i; // change to ans[i] = j; if actual index is needed
// Add current value/index into Fenwick tree
fw.update(id, i);
}
return ans;
}
int main() {
vector<int> a = {8, 2, 5, 3};
auto ans = rightmostSmallerDistance(a);
for (int x : ans) cout << x << ' ';
cout << '\n';
return 0;
}