预处理然后矩阵加速递推
就是预处理的时候还可以以自己作为起点所以还有个自加所以在初始化矩阵的时候我们还需要+1,忽略这点就只有30了= =
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define down(i,a,b) for(int i=a;i>=b;i--) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 10 #define inf 7777777 int n,m; struct matrix { LL a[N][N]; void clear() { memset(a,0,sizeof(a)); } void check() { fo(i,0,m-1) { fo(j,0,m-1) { cout<<a[i][j]; } cout<<endl; } cout<<endl; } matrix operator*(const matrix b)const { matrix anss;anss.clear(); fo(i,0,m-1) fo(j,0,m-1) { fo(k,0,m-1) { anss.a[i][j]+=a[i][k]*(b.a[k][j]); anss.a[i][j]%=inf; } } return anss; } }; matrix I; void getI() { fo(i,0,m-1) fo(j,0,m-1) if(i==j)I.a[i][j]=1; } matrix KSM(matrix a,LL b) { if(b==0)return I; if(b==1)return a; matrix ret=KSM(a,b/2); ret=ret*ret; if(b%2)ret=ret*a; return ret; } int main() { m=read();n=read(); getI(); matrix A,ans,cnt;ans.clear(); ans.a[m-1][0]=1;ans.a[m-2][0]=2; down(i,m-3,0) { LL anss=1; fo(j,i+1,i+m) if(j>=m)break; else anss+=ans.a[j][0]; ans.a[i][0]=anss; } if(n<=m) { cout<<ans.a[m-n][0]<<endl; return 0; } fo(i,0,m-1)A.a[0][i]=1; fo(i,1,m-1) fo(j,0,m-1) if(i==j+1)A.a[i][j]=1; else A.a[i][j]=0; cnt=KSM(A,n-m); // cnt.check(); ans=cnt*ans; // ans.check(); cout<<ans.a[0][0]<<endl; return 0; }