小奇的集合

要分最大值和次大值正负的四种情况...

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rint register int
using namespace std;
inline void read(int &x)
{
    x=0; int ff=1; char q=getchar();
    while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
    while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    x*=ff;
}
inline void readll(ll &x)
{
    x=0; int ff=1; char q=getchar();
    while(q<'0'||q>'9') { if(q=='-') ff=-1; q=getchar(); }
    while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar();
    x*=ff;
}
const int N=100005;
const int mod=10000007;

struct son
{
    ll b[7][7];
    son(){mem(b,0);}
    son operator * (const son &c) const
    {
        int i,j,k;
        son x=*this,t;
        for(i=1;i<=3;++i)
            for(j=1;j<=3;++j)
              for(k=1;k<=3;++k)
                t.b[i][j]=(t.b[i][j]+x.b[i][k]*c.b[k][j]%mod)%mod;
        return t;
    }
    void out()
    {
        for(int i=1;i<=3;++i)
        {
            for(int j=1;j<=3;++j)
                printf("%lld ",b[i][j]);
            printf("\n");
        }
        printf("\n");
    }
}f,a1,a2,a;

int n;
ll K;
ll v[N];

ll work()
{
    rint i,j,k;
    ll an=0;
    sort(v+1,v+1+n);
    for(i=1;i<=n;++i)
        an=(an+v[i])%mod;
    if(K==0)
        return (an+mod)%mod;
    if(v[n]<0)
        return (an+(v[n-1]+v[n]+mod+mod)%mod+mod)%mod;
    f.b[1][1]=v[n-1]; f.b[1][2]=v[n];
    if(v[n-1]<0)
    {
        f.b[1][1]=v[n]+v[n-1];
        an=(an+f.b[1][1])%mod;
        --K;
    }
    a1.b[1][2]=1; a1.b[2][1]=1; a1.b[2][2]=1; a1.b[3][3]=1;
    a2.b[2][3]=1;
    for(i=1;i<=3;++i) a2.b[i][i]=1;
    a=a1*a2;
    //a.out();
    while(K)
    {
        if(K&1)
            f=f*a;
        a=a*a;
        //f.out();
        K>>=1;
    }
    //printf("ff  %lld\n",f.b[1][3]);
    an+=f.b[1][3];
    while(an<=0)
        an+=mod;
    return an%mod;
}

int main(){
    
    //freopen("in.in","r",stdin);
    
    rint i;
    
    read(n); readll(K);
    for(i=1;i<=n;++i)
        readll(v[i]);
    cout<<work();
}
AA

 

posted @ 2017-10-27 06:29  A_LEAF  阅读(115)  评论(0编辑  收藏  举报