//注意到这是一个形如f[i]=a1*f[i-1]+a2*f[i-2]+...+ak[i-k];的方程,立刻就反应到可以使用矩阵乘法进行优化。
//模仿了大神的做法...
//虽然说可以不经过1,但是这是建立在闪烁技能上的,所以仍旧要从头走起
#include <iostream>
#include<cstdio>
#include<cstring>
#define mod 7777777
#define LL __int64
using namespace std;
int n;
typedef class matrix
{
public:
LL num[12][12];
int n,m;
void init(void)
{
memset(num,0,sizeof num);
}
friend matrix operator *(matrix &,matrix &);
}matrix;
matrix operator *(matrix &a,matrix &b)
{
int i,j,t;
matrix tem;
tem.n=a.n;
tem.m=b.m;
for(i=0;i<a.n;i++)
for(j=0;j<b.m;j++)
{
tem.num[i][j]=0;
for(t=0;t<a.m;t++)
tem.num[i][j]=(tem.num[i][j]+a.num[i][t]*b.num[t][j])%mod;
}
return tem;
}
matrix tem,mat,ori;
int main(void)
{
int k,i,j;
scanf("%d%d",&k,&n);
ori.init();
ori.n=k;ori.m=1;
for(i=0;i<k;i++)
{
for(j=0;j<i;j++)
ori.num[i][0]=(ori.num[j][0]+ori.num[i][0])%mod;
ori.num[i][0]++;
}
if(n<=k)
{
printf("%I64d\n",ori.num[n-1][0]%mod);
return 0;
}
mat.init();
mat.n=mat.m=k;
for(i=1;i<k;i++)
mat.num[i-1][i]=1;
for(i=0;i<k;i++)
mat.num[k-1][i]=1;
tem.init();
tem.n=tem.m=k;
for(i=0;i<k;i++)
tem.num[i][i]=1;
n-=k;
while(n)
{
if(n&1)tem=mat*tem;
mat=mat*mat;
n>>=1;
}
mat=tem;
ori=mat*ori;
printf("%I64d\n",ori.num[k-1][0]);
return 0;
}
Warcraft III 守望者的烦恼
最新推荐文章于 2021-10-26 17:43:45 发布