#415 Div2 C

#415 Div2 C

题意

给定一个数字集合,找到所有子集合最大值与最小值之差的和。

分析

列式子,找规律。
$ (a_2 - a_1) * 2^0 + (a_3 - a_1) * 2^1 + ... + (a_n - a_1) * 2^{n-2}$
+ ((a_3 - a_2) * 2^0 + (a_4 - a_2) * 2^1 + ...+ (a_n - a_2) * 2^{n-3})
+ ...
+ ((a_{n-1} - a_{n-2}) * 2^0 + (a_n - a_{n-2}) * 2^1)
+ ((a_n - a_{n-1}) * 2^0)
式子中存在连续的公共项。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 10;
const ll MOD = 1e9 + 7;
ll a[MAXN];
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
    }
    sort(a, a + n);
    ll ans = 0;
    ll s = 0;
    for(int i = 1; i < n; i++) {
        s += a[i];
    }
    s %= MOD;
    ll s1 = s - a[n - 1] + a[0];
    s1 = (s1 + MOD) % MOD;
    ll d = 1;
    for(int i = 1; i < n; i++) {
        (ans += s * d) %= MOD;
        (d <<= 1) %= MOD;
        s -= a[i];
        s = (s + MOD) % MOD;
    }
    d = 1;
    for(int i = n - 2; i >= 0; i--) {
        ans = (ans - s1 * d + MOD) % MOD;
        (d <<= 1) %= MOD;
        s1 = (s1 - a[i] + MOD) % MOD;
    }
    while(ans < 0) ans = (ans + MOD) % MOD;
    cout << ans << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/6926525.html