【jzoj5335】【NOIP2017提高A组模拟8.24】【早苗】【矩阵乘法快速幂】

来源:互联网 发布:tushare mysql 编辑:程序博客网 时间:2024/06/18 05:05

description

这里写图片描述

solution

设f[i][j]表示到第i天,往前j天不同的方案数,可以转移到f[i+1][k],当k<=j时系数是1,当k==j+1时系数是m-j,当然要保证j!=m,可以发现这时可以用矩阵乘法快速幂解决的。

code

#include<set>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define LL long long#define fo(i,j,k) for(LL i=j;i<=k;i++)#define fd(i,j,k) for(LL i=j;i>=k;i--)#define fr(i,j) for(LL i=begin[j];i;i=next[i])using namespace std;LL const mm=100+9,mo=1e9+7;LL n,m,lim,ans[mm][mm],mat[mm][mm],tmp[mm][mm];void multansmat(){    fo(i,1,lim)fo(j,1,lim)tmp[i][j]=0;    fo(i,1,lim)fo(j,1,lim)fo(k,1,lim)tmp[i][k]=(tmp[i][k]+ans[i][j]*mat[j][k])%mo;    fo(i,1,lim)fo(j,1,lim)ans[i][j]=tmp[i][j];}void multmatmat(){    fo(i,1,lim)fo(j,1,lim)tmp[i][j]=0;    fo(i,1,lim)fo(j,1,lim)fo(k,1,lim)tmp[i][k]=(tmp[i][k]+mat[i][j]*mat[j][k])%mo;    fo(i,1,lim)fo(j,1,lim)mat[i][j]=tmp[i][j];}int main(){    freopen("d.in","r",stdin);    freopen("d.out","w",stdout);    scanf("%lld%lld",&n,&m);lim=m;    fo(i,1,m-1){        fo(j,1,i)mat[i][j]=1;        mat[i][i+1]=m-i;    }    ans[1][1]=m;    n--;    while(n){        if(n&1)multansmat();        multmatmat();        n>>=1;    }    LL anss=0;    fo(i,1,m-1)anss=(anss+ans[1][i])%mo;    printf("%lld",anss);    return 0;}
阅读全文
0 0
原创粉丝点击