#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
struct Mat{
LL f[3][3];
};
LL MOD = 10000007;
int a[100010];
Mat mul(Mat a,Mat b)
{
LL i,j,k;
Mat c;
memset(c.f,0,sizeof(c.f));
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
if(a.f[i][j]==0)
continue;
for(k=0;k<3;k++)
{
if(b.f[j][k]==0)
continue;
c.f[i][k]= (c.f[i][k]+a.f[i][j]*b.f[j][k])%MOD;
}
}
return c;
}
Mat pow_mod(Mat e,LL b)
{
Mat s;
memset(s.f,0,sizeof(s.f)) ;
for(int i=0;i<3;i++)
s.f[i][i]=1;
while(b)
{
if(b&1)
s=mul(s,e);
e=mul(e,e);
b=b>>1;
}
return s;
}
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
LL sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sort(a,a+n);
Mat e;
e.f[0][0]=1;e.f[0][1]=1;e.f[0][2]=1;
e.f[1][0]=0;e.f[1][1]=1;e.f[1][2]=1;
e.f[2][0]=0;e.f[2][1]=1;e.f[2][2]=0;
e=pow_mod(e,k);
LL ans=((e.f[0][0]*sum+e.f[0][1]*a[n-1]+e.f[0][2]*a[n-2])%MOD+MOD)%MOD; //可能负数结果
//printf("%lld\n",ans);
printf("%I64d\n",ans);
}
return 0;
}
显然每次会从可重集中选择最大的两个进行操作,设这两数为
a,b(a>=b)
,操作之后的数一定是操作后集合中最大的,下一次选取的数一定是
a+b
和
a
,这就形成了一个类似于斐波那契数列的东西,矩阵乘法快速幂求前n项和即可,转移矩阵如下: