bzoj4547: Hdu5171 小奇的集合

补写一下。

这个看起来就很水啊。

然后的话k很大?那就推推柿子矩乘走起。

然后WA成傻逼,准备四点半回家硬生生拖到五点。

看到abs(a)就觉得哪里不对但是没意识到要判负。。。

矩阵不写了,代码很好懂。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=10000007;

struct Martrix
{
    LL mp[10][10];
}ans,A;
Martrix multi(Martrix a,Martrix b)
{
    Martrix c;
    memset(c.mp,0,sizeof(c));
    for(LL i=1;i<=3;i++)
        for(LL j=1;j<=3;j++)
            for(LL k=1;k<=3;k++)
                c.mp[i][j]=(c.mp[i][j]+(a.mp[i][k]*b.mp[k][j])%mod)%mod;
    return c;
}
void init(LL key,LL k)
{
    memset(ans.mp,0,sizeof(ans.mp));
    ans.mp[1][1]=1;
    ans.mp[2][1]=key;
    ans.mp[3][1]=(1+key)*k%mod;
    A.mp[1][1]=0;A.mp[1][2]=1;A.mp[1][3]=0;
    A.mp[2][1]=1;A.mp[2][2]=1;A.mp[2][3]=0;
    A.mp[3][1]=k;A.mp[3][2]=k;A.mp[3][3]=1;
}

LL a[1100000];
int main()
{
//    freopen("data.in","r",stdin);
//    freopen("lj.out","w",stdout);
    LL n,k;LL sum=0,fmax=-999999999,smax=-999999999;
    scanf("%lld%lld",&n,&k);
    for(LL i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]), sum=(sum+a[i])%mod;
        if(fmax<a[i]){swap(fmax,smax);fmax=a[i];}
        else if(smax<a[i])smax=a[i];
    }
    while(smax<0) sum+=fmax+smax, smax=fmax+smax, k--;
    if(k==0){printf("%lld\n",sum);return 0;}
    else if(k==1){printf("%lld\n",(sum+fmax+smax)%mod);return 0;}
    
    init(1,smax);
    LL p=k-2;
    while(p!=0)
    {
        if(p%2==1)ans=multi(A,ans);
        A=multi(A,A);p/=2;
    }
    sum=(sum+ans.mp[3][1])%mod;
    
    init(2,fmax);
    p=k-2;
    while(p!=0)
    {
        if(p%2==1)ans=multi(A,ans);
        A=multi(A,A);p/=2;
    }
    sum=(sum+ans.mp[3][1])%mod;
    
    printf("%lld\n",sum%mod);
    return 0;
}

 

posted @ 2018-03-12 20:11  AKCqhzdy  阅读(111)  评论(0编辑  收藏  举报