Sequence(矩阵快速幂变形)2018多校第七场

 

题意一目了然,中间会改变的矩阵快速幂。

很显然,我并没有做过这种题,只做过中间不会改变的矩阵快速幂。

于是看题解发现我可以在矩阵中多加一个维度来储存每次加上的一个数,开一个三维矩阵。

| d c  [p/i] |        | f(n-1) |

| 1 0    0   |   *   | f(n-2) |

| 0 0    1   |        |     1   |

 

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int a,b,c,d,p,n;

struct mart
{
    int m[4][4];
    mart(){memset(m,0,sizeof(m));}
}ini;

mart operator * (mart a,mart b)
{
    mart ans;
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
        {
            long long t=0;
            for(int k=1;k<=3;k++)
                t+=(long long)a.m[i][k]*b.m[k][j];
            ans.m[i][j]=t%mod;
        }
    return ans;
}

mart pow(mart a,int b)
{
    mart ans=ini;
    while(b)
    {
        if(b&1)
           ans=a*ans;
        a=a*a;
        b>>=1;
    }
    return ans;
}

void solve()
{
    scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&p,&n);
    if(n==1)    {printf("%d\n",a);return;}
    mart base;
    base.m[1][1]=d;
    base.m[1][2]=c;
    base.m[2][1]=1;
    base.m[3][3]=1;
    for(int i=3;i<=n;)
    {
        if(p/i==0)
        {
            long long ans;
            base=pow(base,n-i+1);
            ans=base.m[1][1]*(long long)b+base.m[1][2]*(long long)a+base.m[1][3];
            ans%=mod;
            printf("%d\n",ans);
            return;
        }
        int j=min(n,p/(p/i));
        mart tbase=base;
        tbase.m[1][3]=p/i;
        tbase=pow(tbase,j-i+1);
        long long A=tbase.m[2][1]*(long long)b+tbase.m[2][2]*(long long)a+tbase.m[2][3];
        long long B=tbase.m[1][1]*(long long)b+tbase.m[1][2]*(long long)a+tbase.m[1][3];
        a=A%mod;b=B%mod;
        i=j+1;
    }
    printf("%d\n",b);
}

int main()
{
    ini.m[1][1]=ini.m[2][2]=ini.m[3][3]=1;
    int num;
    scanf("%d",&num);
    while(num--)
    solve();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值