题意:给n个坐标,你可以挑选任意组合,每个组合的距离为该组合的最大值-最小值,求所有组合的值的和
思路:按坐标从大到小排序后,从0~n-2往后取相邻两点,求这段距离用了多少次*该距离差值,求用的次数:每段距离左边和右边至少个选一个点,即(2的x(左边点的个数)次方-1)*2的y(右边点的个数)次方-1),用快速幂维护一个枚举数组(2的x(点的个数)次方)即可(刚开始忘了快速幂,真的菜)
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 3*100000+10;
long long arr[maxn],pd[maxn];
int n;
const long long ret = 1000000007;
bool cmp(long long a,long long b)
{
return a<b;
}
void node()
{
pd[0] = 0;
for(int i = 1;i<n;i++)
{
long long res = 1,y = i,x = 2;
while(y>0)
{
if(y&1)
res = res * x %ret;
x = x*x%ret;
y>>=1;
}
pd[i] = res-1;
}
}
int main()
{
cin>>n;
node();
for(int i = 0;i<n;i++)
cin>>arr[i];
sort(arr,arr+n,cmp);
long long ans = 0;
for(int i = 0;i<n-1;i++)
{
ans = (ans +(arr[i+1]-arr[i])*(pd[i+1]*pd[n-i-1]%ret)%ret)%ret;
}
cout<<ans;
return 0;
}