bzoj 4547: Hdu5171 小奇的集合
题解:
贪心很简单,分类讨论一下就可以了
用矩阵乘法优化这个过程
由于要维护和所以可以搞成三维矩阵
mo数是1e7+7我写了1e9+7真是很无语
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long #define me(x) memset(x,0,sizeof(x)) #define rint register ll #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) const ll INF=1e9; const ll N=2e5; const ll mo=10000007; ll a[N],n,m; ll max1=-INF,max2=-INF; ll sum; struct re{ ll a[3][3]; re() { me(a); } }now; IL re js(re a,re b) { re c; rep(i,0,2) rep(j,0,2) { rep(k,0,2) { c.a[i][j]+=a.a[i][k]*b.a[k][j]; c.a[i][j]%=mo; } } return(c); } re fsp(ll k) { if (k==1) return(now); re now2=fsp(k/2); now2=js(now2,now2); if (k%2) now2=js(now2,now); return(now2); } ll b[3][3]; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>n>>m; rep(i,1,n) { ll x; cin>>x; if (x>=max1) { max2=max1; max1=x; } else if (x>max2) { max2=x; } sum+=x; sum%=mo; } sum%=mo; if (max1<0) { cout<<((sum+1ll*(max1+max2)*m)%mo+mo)%mo<<endl; exit(0); } else if (max2>=0) { #define b now.a b[0][0]=1; b[0][1]=1; b[0][2]=1; b[1][0]=1; b[1][1]=0; b[1][2]=0; b[2][0]=0; b[2][1]=0; b[2][2]=1; re now2=fsp(m); ll ans=sum+now2.a[0][0]*max1%mo+now2.a[1][0]*max2%mo+now2.a[0][2]*max1%mo+now2.a[1][2]*max2%mo-max1; ans=(ans%mo+mo)%mo; cout<<ans<<endl; } else { ll kk=(-max2+max1-1)/max1; ll ans=0; if (kk<m) { b[0][0]=1; b[0][1]=1; b[0][2]=0; b[1][0]=0; b[1][1]=1; b[1][2]=1; b[2][0]=0; b[2][1]=0; b[2][2]=1; re now2=fsp(kk); ll t1=(max1*now2.a[0][1]+max2*now2.a[1][1])%mo; ans=(sum+t1-max2+now2.a[0][2]*max1+now2.a[1][2]*max2)%mo; max2=t1; b[0][0]=1; b[0][1]=1; b[0][2]=1; b[1][0]=1; b[1][1]=0; b[1][2]=0; b[2][0]=0; b[2][1]=0; b[2][2]=1; now2=fsp(m-kk); ans+=now2.a[0][0]*max1+now2.a[1][0]*max2+now2.a[0][2]*max1+now2.a[1][2]*max2-max1; ans=(ans%mo+mo)%mo; } else { b[0][0]=1; b[0][1]=1; b[0][2]=0; b[1][0]=0; b[1][1]=1; b[1][2]=1; b[2][0]=0; b[2][1]=0; b[2][2]=1; re now2=fsp(m); ll t1=(max1*now2.a[0][1]+max2*now2.a[1][1])%mo; ans=(sum+t1-max2+now2.a[0][2]*max1+now2.a[1][2]*max2)%mo; ans=(ans%mo+mo)%mo; } cout<<ans<<endl; } return 0; }