Codeforces 392-C Yet Another Number Sequence (矩阵快速幂)
求 前A[i]和 工作量巨大, 真是煞人;
A(n)=Fn*(n)^k
另 U(n+1,k)= Fn+1*(n+1)^k; V(n+1,k)=Fn*n^k
(n+1)^k 二项展开 Fn+1 = Fn+Fn-1 == (n+1)^k*U(n,i)+(n+1)^k*V(n,i)
构造矩阵; 二项展开与 杨辉三角有关
2k+3 的矩阵; 三个杨辉三角;
注意 n 和 k 都用long long
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <queue> #include <stack> #include <set> #include <bitset> #include <vector> using namespace std; typedef long long ll; const double PI=acos(-1); const int INF=0x3f3f3f3f; const double esp=1e-6; const int MAXN=100; const int N=120; const int MOD=1e9+7; #define mem(a,b) memset(a,b,sizeof(a)) ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){ return b/gcd(a,b)*a;} ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;} ll C[202][205]; void tab_init() { C[0][0]=1; for(int i=1;i<=50;i++) for(int j=0;j<=i;j++){ C[i][j]=(j==0)?1:(C[i-1][j]+C[i-1][j-1])%MOD; } } ll n,k; struct Matrix{ ll arr[N][N]; void init() { memset(arr,0,sizeof(arr)); for(int i=0;i<MAXN;i++) arr[i][i]=1;//初始化 } void iinit() { memset(arr,0,sizeof(arr)); for(int i=0;i<=k;i++) for(int j=0;j<=i;j++) { arr[i][j]=arr[i+k+1][j]=arr[i][j+k+1]=C[i][j]; } arr[2*k+2][k]=arr[2*k+2][2*k+2]=1; } }; Matrix mul(Matrix X,Matrix Y)// 矩阵乘法 { Matrix ans; for(int i=0;i<MAXN;i++) for(int j=0;j<MAXN;j++){ ans.arr[i][j]=0; for(int k=0;k<MAXN;k++){ ans.arr[i][j]+=X.arr[i][k]*Y.arr[k][j]; ans.arr[i][j]%=MOD; } } return ans; } Matrix Q_pow(Matrix B,ll n)// 矩阵快速幂 { Matrix ans; ans.init(); while(n) { if(n&1) ans=mul(ans,B); n>>=1; B=mul(B,B); } return ans; } int main() { tab_init(); while(~scanf("%I64d %I64d",&n,&k)) { Matrix ans; ans.iinit(); ans=Q_pow(ans,n); ll res=0; for(int i=0;i<2*k+2;i++) res+=(ans.arr[2*k+2][i])%MOD; printf("%I64d\n",res%MOD); } return 0; }
123
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!