<p>You are given two <strong>0-indexed</strong> arrays <code>nums1</code> and <code>nums2</code> of length <code>n</code>, both of which are <strong>permutations</strong> of <code>[0, 1, ..., n - 1]</code>.</p>

<p>A <strong>good triplet</strong> is a set of <code>3</code> <strong>distinct</strong> values which are present in <strong>increasing order</strong> by position both in <code>nums1</code> and <code>nums2</code>. In other words, if we consider <code>pos1<sub>v</sub></code> as the index of the value <code>v</code> in <code>nums1</code> and <code>pos2<sub>v</sub></code> as the index of the value <code>v</code> in <code>nums2</code>, then a good triplet will be a set <code>(x, y, z)</code> where <code>0 &lt;= x, y, z &lt;= n - 1</code>, such that <code>pos1<sub>x</sub> &lt; pos1<sub>y</sub> &lt; pos1<sub>z</sub></code> and <code>pos2<sub>x</sub> &lt; pos2<sub>y</sub> &lt; pos2<sub>z</sub></code>.</p>

<p>Return <em>the <strong>total number</strong> of good triplets</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums1 = [2,0,1,3], nums2 = [0,1,2,3]
<strong>Output:</strong> 1
<strong>Explanation:</strong> 
There are 4 triplets (x,y,z) such that pos1<sub>x</sub> &lt; pos1<sub>y</sub> &lt; pos1<sub>z</sub>. They are (2,0,1), (2,0,3), (2,1,3), and (0,1,3). 
Out of those triplets, only the triplet (0,1,3) satisfies pos2<sub>x</sub> &lt; pos2<sub>y</sub> &lt; pos2<sub>z</sub>. Hence, there is only 1 good triplet.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums1 = [4,0,1,3,2], nums2 = [4,1,0,2,3]
<strong>Output:</strong> 4
<strong>Explanation:</strong> The 4 good triplets are (4,0,3), (4,0,2), (4,1,3), and (4,1,2).
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>n == nums1.length == nums2.length</code></li>
	<li><code>3 &lt;= n &lt;= 10<sup>5</sup></code></li>
	<li><code>0 &lt;= nums1[i], nums2[i] &lt;= n - 1</code></li>
	<li><code>nums1</code> and <code>nums2</code> are permutations of <code>[0, 1, ..., n - 1]</code>.</li>
</ul>

class SegNode:
    def __init__(self, l, r, val, left=None, right=None):
        self.l = l  # Left index of the range
        self.r = r  # Right index of the range
        self.val = val  # The sum stored in the node
        self.left = left  # Left child node
        self.right = right  # Right child node

class SegmentTree:
    def __init__(self, values):
        self.values = values
        self.root = self.build(0, len(values) - 1)

    def build(self, l, r):
        if l == r:
            # Leaf node: represents a single element in the array
            return SegNode(l, r, self.values[l])
        m = (l + r) // 2
        # Recursively build the left and right subtrees
        left = self.build(l, m)
        right = self.build(m + 1, r)
        # The current node's value is the sum of the left and right children
        return SegNode(l, r, left.val + right.val, left, right)

    def query(self, l, r, a, b, node=None):
        if node is None:
            node = self.root
        
        # If the range of the node is completely outside the query range
        if l > b or r < a:
            return 0
        
        # If the range of the node is completely within the query range
        if l >= a and r <= b:
            return node.val
        
        # Otherwise, query the left and right subtrees
        mid = (l + r) // 2
        left_val = self.query(l, mid, a, b, node.left)
        right_val = self.query(mid + 1, r, a, b, node.right)
        return left_val + right_val

    def update(self, index, new_value, node=None):
        if node is None:
            node = self.root
        
        # If the index is outside the range of this node, do nothing
        if index < node.l or index > node.r:
            return node.val
        
        # If this node is a leaf node, update its value
        if node.l == node.r:
            node.val = new_value
            return node.val
        
        # Otherwise, update the left or right subtree
        mid = (node.l + node.r) // 2
        if index <= mid:
            left_val = self.update(index, new_value, node.left)
            right_val = node.right.val
        else:
            left_val = node.left.val
            right_val = self.update(index, new_value, node.right)
        
        # Update the current node's value
        node.val = left_val + right_val
        return node.val

class Solution:
    def goodTriplets(self, nums1, nums2):
        n = len(nums1)
        v = [0] * (n + 1)
        ans = 0
        pos_in_nums2 = {num: i + 1 for i, num in enumerate(nums2)}
        
        # Initialize the segment tree with all zeroes
        seg_tree = SegmentTree([0] * (n + 1))
        
        # Update the segment tree with the position of the first element in nums1
        seg_tree.update(pos_in_nums2[nums1[0]], 1)
        
        for i in range(1, n):
            r = pos_in_nums2[nums1[i]]
            q = seg_tree.query(1, n, 1, r)
            d = i - q
            loc = (n - r) - d
            ans += loc * q
            
            # Update the segment tree with the current position in nums2
            seg_tree.update(r, 1)
        
        return ans
2244