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;
}

 

posted @ 2018-08-17 14:24  尹吴潇  阅读(119)  评论(0编辑  收藏  举报