Notes

Today

2552. Count Increasing Quadruplets

Given a 0-indexed integer array nums of size n containing all numbers from 1 to n, return the number of increasing quadruplets.

A quadruplet (i, j, k, l) is increasing if:

0 <= i < j < k < l < n, and
nums[i] < nums[k] < nums[j] < nums[l].

Constraints:

4 <= nums.length <= 4000
1 <= nums[i] <= nums.length

All the integers of nums are unique. nums is a permutation.


// left[i][a[j]]  means the count of "until i, < a[j]"
// right[j][a[i]] means the count of "unitl j, > a[i]"

class Solution {
public:
    long long countQuadruplets(vector<int>& a) {
        long long res = 0;
        int n = a.size();
        vector<vector<int>> left(n, vector<int>(n+1, 0));
        vector<vector<int>> right(n, vector<int>(n+1, 0));
        for (int i = 1; i < n; ++i) {
            // new array will based on the old array
            left[i] = left[i-1];
            // update all the elements greater than a[i-1]
            for (int j = a[i-1] + 1; j <= n; ++j)
                left[i][j]++;
        }
        for (int i = n-2; i >= 0; --i) {
            right[i] = right[i+1];
            for (int j = 0; j < a[i+1]; ++j)
                right[i][j]++;
        }
        for (int i = 0; i < n; ++i) {
            for (int j = n-1; j > i; --j) {
                if (a[i] <= a[j]) continue;
                // i < j && a[i] > a[j] -- these are actual nums[k] < nums[j]
                // left[i][a[j]] means the count of "until i, < a[j]"
                // right[j][a[i]] means the count of "unitl j, > a[i]"
                res += left[i][a[j]] * right[j][a[i]];
            }
        }
        return res;
    }
};

Intuition:

dp[j] stores the count of all valid triplets (i, j, k) that satisfies i < j < k and nums[i] < nums[k] < nums[j] when using the current number as the role j in Quadruplets.

During iteration, we also update previous dp[i] by keeping track of the amount of smaller numbers in front of each new value.

If nums[j] < nums[i], the new value is a potential k for j in the future, so add its previous_small to the dp[i].

class Solution:
    def countQuadruplets(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [0] * n
        ans = 0
        for j in range(n):
            prev_small = 0
            for i in range(j):
                if nums[j] > nums[i]:
                    prev_small += 1
                    ans += dp[i]
                elif nums[j] < nums[i]:
                    dp[i] += prev_small
        return ans