<p>You are given two <strong>0-indexed</strong> arrays <code>nums</code> and <code>cost</code> consisting each of <code>n</code> <strong>positive</strong> integers.</p>

<p>You can do the following operation <strong>any</strong> number of times:</p>

<ul>
	<li>Increase or decrease <strong>any</strong> element of the array <code>nums</code> by <code>1</code>.</li>
</ul>

<p>The cost of doing one operation on the <code>i<sup>th</sup></code> element is <code>cost[i]</code>.</p>

<p>Return <em>the <strong>minimum</strong> total cost such that all the elements of the array </em><code>nums</code><em> become <strong>equal</strong></em>.</p>

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

<pre>
<strong>Input:</strong> nums = [1,3,5,2], cost = [2,3,1,14]
<strong>Output:</strong> 8
<strong>Explanation:</strong> We can make all the elements equal to 2 in the following way:
- Increase the 0<sup>th</sup> element one time. The cost is 2.
- Decrease the 1<sup><span style="font-size: 10.8333px;">st</span></sup> element one time. The cost is 3.
- Decrease the 2<sup>nd</sup> element three times. The cost is 1 + 1 + 1 = 3.
The total cost is 2 + 3 + 3 = 8.
It can be shown that we cannot make the array equal with a smaller cost.
</pre>

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

<pre>
<strong>Input:</strong> nums = [2,2,2,2,2], cost = [4,2,8,1,3]
<strong>Output:</strong> 0
<strong>Explanation:</strong> All the elements are already equal, so no operations are needed.
</pre>

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

<ul>
	<li><code>n == nums.length == cost.length</code></li>
	<li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= nums[i], cost[i] &lt;= 10<sup>6</sup></code></li>
	<li>Test cases are generated in a way that the output doesn&#39;t exceed&nbsp;2<sup>53</sup>-1</li>
</ul>

class Solution {
public:
//after peeking at editorial
    // long long ops(int num, vector<long long>& prefix, unordered_map<int,int>& index){
    //     //needs to be O(1)
    //     //hm...just do n for now
    //     // int pos = index[num];

    // }
    long long minCost(vector<int>& nums, vector<int>& cost) {
        //sort nums so in order
        vector<pair<int,int>> temp;
        for(int i=0; i<nums.size(); i++){
            temp.push_back({nums[i],cost[i]});
        }
        sort(temp.begin(), temp.end(), less<pair<int,int>>());

        // 1 2 3 4
        vector<long long> prefix;                   // 0  1 3 6 10
        vector<long long> suffix(cost.size()+1, 0); // 10 9 7 4 0

        prefix.push_back(0);
        for(pair<int,int> p:temp){
            prefix.push_back(prefix.back()+p.second);
        }
        for(int i=temp.size()-1; i>=0; i--){
            suffix[i] = suffix[i+1]+temp[i].second;
        }

        long long cur = 0;
        //calculate initial cost
        for(int i=1; i<temp.size(); i++){
            cur += (long long)(temp[i].first-temp[0].first) * temp[i].second;
        }
        cout << cur;
        long long ans = cur;
        for(int i=1; i<temp.size(); i++){
            // cout << " + " << (cost[i]-cost[i-1])*prefix[i];
            // cout << " - " << (cost[i]-cost[i-1])*suffix[i] << endl;
            cur += (temp[i].first-temp[i-1].first)*prefix[i];
            cur -= (temp[i].first-temp[i-1].first)*suffix[i];
            ans = min(ans, cur);
        }
        return ans;

        // //bin search? is it monotonic, tho...no
        // sort(nums.begin(), nums.end(),[&](int l, int r){
        //     return ops(l, prefix, index) < ops(r, prefix, index);
        // });
        
        
    }
};

//2 5 10
//4 8 9
/*
-> 10? 8*4 + 5*8 
-> 9? 7*4 + 4*8 + 1*9
4|x-a| + 8|x-b| + 9|x-c|
*/
50600