891. Sum of Subsequence Widths
Posted habibah-chang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了891. Sum of Subsequence Widths相关的知识,希望对你有一定的参考价值。
问题:
给定数组,求所有子数组的最大值最小值之差的总和是多少。
这个数若太大了,对其进行取kMod=10^9+7的模
Example 1: Input: [2,1,3] Output: 6 Explanation: Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3]. The corresponding widths are 0, 0, 0, 1, 1, 2, 2. The sum of these widths is 6. Note: 1 <= A.length <= 20000 1 <= A[i] <= 20000
解法:
求所有子数组的最大最小之之差 的和,即是:
所有子数组的最大值之和-最小值之和。
★先对A进行排序。
那么对于其中任意A[i]
1.若在某个子数组中,A[i]=最大值:那么该子数组的元素<=A[i]
★(因为已排序)这样的子数组共有,2^i 个。
那么对于A[i]作为最大值,对res的贡献即是+A[i],所以总贡献为:+ (A[i] * 2^i)
2.若在某个子数组中,A[i]=最小值:那么该子数组的元素>=A[i]
★(因为已排序)这样的子数组共有,2^(n-i-1) 个。(n=A.size())
那么对于A[i]作为最小值,对res的贡献即是-A[i],所以总贡献为:- (A[i] * 2^(n-i-1))
3.因此对于每一个A[i],对res的贡献为:
(A[i] * 2^i) - (A[i] * 2^(n-i-1))
那么所有的元素的贡献和为:
res= Sum(A[i] * 2^i) - (A[i] * 2^(n-i-1)), 1<=i<n
为了简化每次单独计算 2^i 和 2^(n-i-1) 的重复性。我们可以展开上述式子,
合并同样为 2^i 的项。
做如下转换:
可得:
res = Sum(A[i] * 2^i - A[n-i-1] * 2^i)
= Sum((A[i] - A[n-i-1]) * 2^i) , 1<=i<n
另p=2^i
i=0时,p=1,
i=1时,p=p*2=p<<1
......
由于p可能会成为一个非常大的数,因此我们在循环计算途中,最好同时取模
(a+b)%kMod = (a%kMod + b%kMod) %kMod
(a*b)%kMod = (a%kMod * b%kMod) %kMod
所以:p=(p<<1)%kMod
参考代码:
1 class Solution { 2 public: 3 int sumSubseqWidths(vector<int>& A) { 4 long res=0, p=1; 5 long kMod=1e9+7;//科学计数法 1e9=1*10^9 1.34e-5=1.34*10^(-5) 6 sort(A.begin(), A.end()); 7 int n=A.size(); 8 for(int i=0; i<n; i++){ 9 res = (res + (A[i]-A[n-i-1])*p) % kMod; 10 p = (p<<1) % kMod; 11 } 12 return res; 13 } 14 };
以上是关于891. Sum of Subsequence Widths的主要内容,如果未能解决你的问题,请参考以下文章
1104. Sum of Number Segments (20)数学题——PAT (Advanced Level) Practise
1104. Sum of Number Segments (20)数学题——PAT (Advanced Level) Practise
727. Minimum Window Subsequence