http://acm.split.hdu.edu.cn/showproblem.php?pid=5171
s(n)=s(n-1)+f(n-1)+f(n-2)
f(n)=f(n-1)+f(n-2)
s(k)=(a^k*b)%mod
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define N 3
#define ll long long
#define mod 10000007
const int maxn=100010;
using namespace std;
struct Mat {
ll mat[N][N];
};
Mat operator * (Mat a, Mat b) {
Mat c;
memset(c.mat, 0, sizeof(c.mat));
for(int k = 0; k < N; ++k) {
for(int i = 0; i < N; ++i) {
if(a.mat[i][k]==0) continue;//剪枝
for(int j = 0; j < N; ++j) {
if(b.mat[k][j]==0) continue;//剪枝
c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
c.mat[i][j]%=mod;
}
}
}
return c;
}
Mat operator ^ (Mat a, int k) {
Mat c;
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
c.mat[i][j] = (i == j); //初始化为单位矩阵
for(; k; k >>= 1) {
if(k&1) c = c*a;
a = a*a;
}
return c;
}
int a[maxn];
int main()
{
int n, k;
while(scanf("%d %d", &n, &k) != EOF)
{
ll sum = 0;
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
sum += a[i];
}
sort(a, a + n);
Mat tmp;
tmp.mat[0][0] = 1; tmp.mat[0][1] = 1; tmp.mat[0][2] = 1;
tmp.mat[1][0] = 0; tmp.mat[1][1] = 1; tmp.mat[1][2] = 1;
tmp.mat[2][0] = 0; tmp.mat[2][1] = 1; tmp.mat[2][2] = 0;
tmp = tmp^k;
ll ans = (tmp.mat[0][0] * sum + tmp.mat[0][1] * a[n - 1] + tmp.mat[0][2] * a[n - 2]) % mod;
printf("%lld\n", ans);
}
return 0;
}