[bzoj]4547小奇的集合
先排序找最大的两个数x1,x2
然后发现 两个数都大于0时可以矩阵优化算出和 其他情况特判一下
- 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=10000007;
int n,k;
ll s[100010],res;
struct Matrix {
ll a[10][10];
int n;
ll* operator [] (int x) {
return a[x];
}
Matrix operator* (Matrix b) {
Matrix c;
c.n=n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
c[i][k]=(c[i][k]+a[i][j]*b[j][k])%mod;
return c;
}
Matrix operator^ (int e) {
Matrix res,tmp=*this;
res.init(n);
while(e) {
if(e&1) res=res*tmp;
tmp=tmp*tmp;
e>>=1;
}
return res;
}
void init(int k) {
n=k;for(int i=1;i<=n;i++) a[i][i]=1;
}
Matrix() {
memset(a,0,sizeof(a));
}
}g;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
scanf("%lld",&s[i]);
sort(s+1,s+n+1);
if(s[n]<0&&s[n-1]<0){
res=k*(s[n]+s[n-1])%mod;
for(int i=1;i<=n;i++)res=(res+s[i]+mod)%mod;
printf("%lld\n",res);
return 0;
}
if(s[n-1]<0&&s[n]>0){
int p=(-s[n-1]-1)/(s[n])+1;
p=min(p,k);
res+=1ll*(p)*s[n-1]+(1ll*p*(p-1)/2)%mod*s[n]%mod;
k-=p;
s[n-1]=p*s[n]+s[n-1];
}
g.n=3,g[2][1]=1,g[1][1]=2,g[1][3]=-1,g[3][2]=1;
g=g^k;
res+=(1ll*g[1][1]*(s[n]+s[n-1])%mod+1ll*g[1][2]*s[n-1]%mod+mod)%mod;
res%=mod;
for(int i=1;i<=n-2;i++){
res+=s[i];res%=mod;
if(res<0)res+=mod;
}
printf("%lld\n",res);
}