https://codeforces.com/problemset/problem/809/A?f0a28=1
题目大意
求数列所有的不同子集(元素个数大于等于2),
然后求所有子集内最大数减最小数的和。
思路
当x被用作最大/最小数时,对答案的贡献要么是加x,要么是减x
这就意味着,我们可以计算这个数被加减的次数来获得答案
容易得出
排序后x前有k个数,就会被加上 2^k 次;
排序后x后有m个数,就会被减 2^m 次(注意减的话要加上mod再取模,防止出现负数)
快速幂求2的幂次即可
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>using namespace std;
#define endl '\n'
#define int long long
const int N = 3e5 + 10, mod = 1e9 + 7;
int a[N],s[N];int qmi(int a, int k, int p) // 求a^k mod p
{int res = 1 % p;while (k){if (k & 1) res = res * a % p;a = a * a % p;k >>= 1;}return res;
}void solve()
{int n,num = 0;cin >> n;for(int i = 1; i <= n; i ++) cin >> a[i];sort(a + 1, a + n + 1);for(int i = 1; i <= n; i ++){num = num + a[i] * qmi(2, (i-1), mod) % mod;num %= mod;num = num - a[i] * qmi(2, (n-i), mod) % mod;num = (num + mod) % mod;}cout << num << endl;
}signed main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);int T = 1;//cin >> T;while(T --){solve();}return 0;
}