[BZOJ4547]小奇的集合(矩阵乘法)

题目:

我是超链接

题解:

数据范围和转移的相同性让我们很容易判断出来是个矩阵乘法
设计也很简单|sum max1 max2|*系数矩阵
写的时候有一个细节问题,就是当max1=1,max2=-1的时候,按照我们的转移,转移一步之后的结果是max1=0,max2=1,显然不符合大小关系了,事实上只要最大值最小值是一正一副就会出现这种情况,那么我们要处理一下,处理的过程中不要忘记这个时候的sum&k也是变化的

代码:

#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
#define INF 1e9
const int mod=10000007;
struct mat
{
    LL sq[5][5];
    void clear(){memset(sq,0,sizeof(sq));}
}ans,mul;
mat cf(mat a,mat b,int id)
{
    mat c;c.clear();
    for (int i=1;i<=id;i++)
      for (int j=1;j<=3;j++)
        for (int k=1;k<=3;k++)
          c.sq[i][j]=(c.sq[i][j]+a.sq[i][k]*b.sq[k][j]%mod)%mod;
    return c;
}
mat ksm(mat a,LL k)
{
    mat ans=a;k--;
    for (;k;k>>=1,a=cf(a,a,3))
      if (k&1) ans=cf(ans,a,3);
    return ans;
}
int main()
{
    int n,k;scanf("%d%d",&n,&k);
    LL max1=-INF,max2=-INF,x;
    for (int i=1;i<=n;i++)
    {
        scanf("%lld",&x);
        if (x>max1) max2=max1,max1=x;
        else if (x>max2) max2=x;
        ans.sq[1][1]=(x+ans.sq[1][1])%mod;
    }
    while (max2<0 && k) k--,max2+=max1,ans.sq[1][1]=(max2+ans.sq[1][1])%mod;
    ans.sq[1][2]=max1; ans.sq[1][3]=max2;
    mul.sq[1][1]=1;mul.sq[2][1]=1;mul.sq[3][1]=1;mul.sq[2][2]=1;
    mul.sq[3][2]=1;mul.sq[2][3]=1;
    mul=ksm(mul,k);ans=cf(ans,mul,1);
    printf("%lld",ans.sq[1][1]);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值