题目描述
AC代码
将数组 A 从小到大排序。
假如我们固定了当前子序列的最小值 A[i],假设数组下标从 0 开始,则以 A[i]为最小值贡献的答案为,
(
A
[
n
−
1
]
−
A
[
i
]
)
2
n
−
i
−
2
+
(
A
[
n
−
2
]
−
A
[
i
]
)
2
n
−
i
−
3
+
⋯
+
(
A
[
i
+
1
]
−
A
[
i
]
)
2
0
(A[n−1]−A[i])2^n−i−2+(A[n−2]−A[i])2^n−i−3+⋯+(A[i+1]−A[i])2^0
(A[n−1]−A[i])2n−i−2+(A[n−2]−A[i])2n−i−3+⋯+(A[i+1]−A[i])20。将括号打开,一部分为
−
A
[
i
]
⋅
(
2
n
−
i
−
1
−
1
)
−A[i]⋅(2^n−i−1−1)
−A[i]⋅(2n−i−1−1),另一部分是
S
(
i
)
=
∑
n
−
1
k
=
i
+
1
A
[
k
]
⋅
2
k
−
i
−
1
S(i)=∑n−1 k=i+1A[k]⋅2k−i−1
S(i)=∑n−1k=i+1A[k]⋅2k−i−1。
第二部分不能每次枚举计算,但可以找到递推公式,即
S
(
i
)
=
2
S
(
i
+
1
)
+
A
[
i
+
1
]
S(i)=2S(i+1)+A[i+1]
S(i)=2S(i+1)+A[i+1],其中
S
(
n
−
1
)
=
0
S(n−1)=0
S(n−1)=0。
然后我们可以从
i
=
n
−
2
i=n−2
i=n−2开始到
i
=
0
i=0
i=0枚举统计答案即可。
class Solution {
int mod=1000000007;
public int sumSubseqWidths(int[] A) {
Arrays.sort(A);
long res=0,p=1,sum=0;
for(int x:A){
res=(res+x*(p-1)-sum)%mod;
sum=(sum*2+x)%mod;
p=p*2%mod;
}
return (int)(res+mod)%mod;
}
}