fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<int, int> ii;
  6.  
  7. const int INF = 1e9;
  8. const ll LINF = 1e18;
  9.  
  10. const int N = 2e5 + 5;
  11. const int LOG = 18;
  12.  
  13. int n;
  14. int a[N];
  15. int f[LOG][N]; // f[k][i] = Min của đoạn bắt đầu từ i và có độ dài 2^k
  16.  
  17. // Tương đương với floor(log2(x)) nhưng tránh được số thực
  18. int log2_floor(int x) {
  19. return 31 - __builtin_clz(x);
  20. }
  21.  
  22. void precompute() { // O(n * log2(n))
  23. for (int i = 1; i <= n; i++) f[0][i] = a[i];
  24.  
  25. for (int k = 1; k < LOG; k++) {
  26. for (int i = 1; i + (1 << k) - 1 <= n; i++) {
  27. f[k][i] = min(f[k - 1][i], f[k - 1][i + (1 << (k - 1))]);
  28. }
  29. }
  30. }
  31.  
  32. // Min của đoạn [l, r]
  33. int getMin(int l, int r) { // O(1)
  34. int k = log2_floor(r - l + 1);
  35. return min(f[k][l], f[k][r - (1 << k) + 1]);
  36. }
  37.  
  38. // Phần tử gần nhất bên trái < a[i]
  39. int prevSmaller(int i) { // O(log2(n))
  40. int l = 1, r = i - 1, ans = 0;
  41. while (l <= r) {
  42. int mid = (l + r) >> 1;
  43.  
  44. if (getMin(mid, i) < a[i]) {
  45. ans = mid;
  46. l = mid + 1;
  47. }
  48. else {
  49. r = mid - 1;
  50. }
  51. }
  52. return ans;
  53. }
  54.  
  55. int main() {
  56. ios::sync_with_stdio(0); cin.tie(0);
  57. cin >> n;
  58. for (int i = 1; i <= n; i++) cin >> a[i];
  59.  
  60. precompute();
  61.  
  62. for (int i = 1; i <= n; i++) {
  63. cout << prevSmaller(i) << ' ';
  64. }
  65. }
Success #stdin #stdout 0.01s 5520KB
stdin
8
2 5 1 4 8 3 2 5
stdout
0 1 0 3 4 3 3 7