14042: 【原4042】面包要约会
题目
题目描述
author: MW 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4042
Description
面包决定要移民缅甸。他一到达目的地就开始进行黑客活动。目前,他一共黑掉了它所住街区中的n台电脑,而这些电脑又恰好在一条直线上。
现在用序号\(1-n\)来表示面包黑掉的电脑,其中第i台电脑位于坐标\(x_i\)处,且每台电脑的坐标都不相同。
面包决定在繁重的工作后休息一下。因此他邀请他的小姐姐到一家餐馆吃饭。但是小姐姐说她愿意去,但是有一个条件:面包必须解决一个简单的任务
首先,\(A\)是所有被面包黑掉的电脑构成的集合,函数\(F(a) = \max_{i,j \in a} |x_i-x_j|\) , 其中\(a\)是\(A\)的一个非空子集。小姐姐让面包计算这样一个和式 \(\sum_{a\subseteq A, a\not= \phi}F(a)\),由于结果非常大,小姐姐让面包对结果模1e9+7
然而,面包实在是太累了,他没办法完成这个任务,请你来帮助他成功参加约会吧。
Input Format
第一行,有一个整数n(\(1\leq n\leq 3e5\)), 表示被黑的电脑数目
第二行,有n个整数\(x_1,x_2,\cdots ,x_n(1\leq x_i \leq 1e9)\) 代表被黑电脑的坐标,并保证所有\(x_i\)不同。
Output Format
一个整数——要求模1e9+7
Sample Input 1
2
4 7
Sample Output 1
3
Sample Input 2
3
4 3 1
Sample Output 2
9
样例解释
在样例2中,一共有7个非空子集。其中只有\(\{4,3\},\{4,1\},\{3,1\},\{4,3,1\}\)会使结果增加。最后的结果为\((4-3)+(4-1)+(3-1)+(4-1)=9\)
Limits
对于50%的数据,\(1\leq n \leq 20\)
对于100%的数据,\(1\leq n\leq 3e5\)
其中\(1\leq x_i \leq 1e9\)
FineArtz's solution
/* 面包要约会 */
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
constexpr int MAXN = 3e5 + 5, MOD = 1e9 + 7;
int n;
long long x[MAXN];
int main(){
cin >> n;
for (int i = 1; i <= n; ++i) cin >> x[i];
sort(x + 1, x + n + 1);
long long ans = 0, doub = 1, sum = 0;
for (int i = 2; i <= n; ++i){
sum = sum * 2 % MOD;
sum = (sum + x[i - 1]) % MOD;
doub = doub * 2 % MOD;
ans = (ans + (doub - 1) * x[i] - sum) % MOD;
}
cout << ans << endl;
return 0;
}
ligongzzz's solution
#include "iostream"
#include "cstdio"
using namespace std;
constexpr long long mod = (long long)(1e9 + 7);
int pos[300009] = { 0 };
template <class T, class T_val = decltype(*declval<T>()),
class Compare = bool (*)(T_val, T_val)>
void quick_sort(T start, T end,
Compare cmp = [](T_val a, T_val b) {return a < b; }) {
if (start == end)
return;
auto i = start, j = end;
--j;
if (i == j)
return;
//交换
auto key = *start;
for (bool status = true; i != j;) {
if (status) {
if (cmp(*j, key)) {
*i = *j;
++i;
status = false;
}
else
--j;
}
else {
if (cmp(key, *i)) {
*j = *i;
--j;
status = true;
}
else
++i;
}
}
*i = key;
//递归
quick_sort(start, ++i, cmp);
quick_sort(i, end, cmp);
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i)
scanf("%d", &pos[i]);
quick_sort(pos, pos + n);
long long ans = 0, cur_ans = 0, cnt = 0;
for (int i = 1; i < n; ++i) {
cnt = (cnt * 2 + 1) % mod;
cur_ans = (cur_ans * 2 + (pos[i] - pos[i - 1]) * cnt) % mod;
ans = (ans + cur_ans) % mod;
}
cout << ans;
return 0;
}
skyzh's solution
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const long long M = 1e9 + 7;
inline long long fast_expr(long long a, long long b) {
long long sum = 1;
while (b > 0) {
if (b & 1) sum = (sum * a) % M;
b >>= 1;
a = (a * a) % M;
}
return sum;
}
int main() {
int n;
int pos[300000];
long long sum = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &pos[i]);
sort(pos, pos + n);
for (int i = 0; i < n; i++) {
long long addend = fast_expr(2, i) - fast_expr(2, n - i - 1);
sum = (sum + (addend * pos[i] % M)) % M;
}
sum = (sum + M) % M;
cout << sum << endl;
return 0;
}