【 CodeForces - 392C】 Yet Another Number Sequence (二项式展开+矩阵加速)

Description

Everyone knows what the Fibonacci sequence is. This sequence can be defined by the recurrence relation:

F1 = 1, F2 = 2, Fi = Fi - 1 + Fi - 2 (i > 2).

We'll define a new number sequence Ai(k) by the formula:

Ai(k) = Fi × ik (i ≥ 1).

In this problem, your task is to calculate the following sum: A1(k) + A2(k) + ... + An(k). The answer can be very large, so print it modulo1000000007 (109 + 7).

Input

The first line contains two space-separated integers nk (1 ≤ n ≤ 1017; 1 ≤ k ≤ 40).

Output

Print a single integer — the sum of the first n elements of the sequence Ai(k) modulo 1000000007 (109 + 7).

Sample Input

Input
1 1
Output
1
Input
4 1
Output
34
Input
5 2
Output
316
Input
7 4
Output
73825
 

 

【分析】

  哈哈照着上一题的方法我就弄出来了~~
  应该是形如 x^k的形式,x很大,k较小的时候可以用二项式定理展开,求递推式然后矩阵加速。。
  


  就这样,qpow n次就好啦~

代码如下:
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 #define Mod 1000000007
10 #define Maxn 110
11 #define LL long long
12 
13 struct node
14 {
15     LL a[Maxn][Maxn];
16 }t[5];
17 
18 LL c[Maxn][Maxn];
19 LL n,k;
20 
21 void init()
22 {
23     memset(c,0,sizeof(c));
24     for(LL i=0;i<=80;i++) c[i][0]=1;
25     for(LL i=1;i<=80;i++)
26      for(LL j=1;j<=80;j++)
27         c[i][j]=(c[i-1][j-1]+c[i-1][j])%Mod;
28 }
29 
30 void get_m()
31 {
32     for(LL i=k+1;i<=2*k+1;i++)
33     {
34         for(LL j=0;j<=i-k-1;j++) t[0].a[i][j]=c[i-k-1][j];
35         for(LL j=i+1;j<=2*k+2;j++) t[0].a[i][j]=0;
36     }
37     for(LL i=0;i<=k;i++)
38     {
39         for(LL j=0;j<=i;j++) t[0].a[i][j]=t[0].a[i][j+k+1]=c[i][j];
40         for(LL j=i+1;j<=k;j++) t[0].a[i][j]=t[0].a[i][j+k+1]=0;
41         t[0].a[i][2*k+2]=0;
42     }
43     for(LL i=0;i<=2*k+1;i++) t[0].a[2*k+2][i]=0;
44     t[0].a[2*k+2][2*k+2]=t[0].a[2*k+2][k]=1;
45 }
46 
47 void get_un()
48 {
49     memset(t[1].a,0,sizeof(t[1].a));
50     for(LL i=0;i<=2*k+2;i++) t[1].a[i][i]=1;
51 }
52 
53 void mul(LL x,LL y,LL z)
54 {
55     for(LL i=0;i<=2*k+2;i++)
56      for(LL j=0;j<=2*k+2;j++)
57      {
58          t[2].a[i][j]=0;
59          for(LL l=0;l<=2*k+2;l++)
60             t[2].a[i][j]=(t[2].a[i][j]+t[y].a[i][l]*t[z].a[l][j])%Mod;
61      }
62     t[x]=t[2];
63 }
64 
65 void qpow(LL b)
66 {
67     get_un();
68     while(b)
69     {
70         if(b&1) mul(1,0,1);
71         mul(0,0,0);
72         b>>=1;
73     }
74 }
75 
76 int main()
77 {
78     init();
79     scanf("%lld%lld",&n,&k);
80     get_m();
81     qpow(n);
82     LL ans=0;
83     for(LL i=0;i<2*k+2;i++) ans=(ans+t[1].a[2*k+2][i])%Mod;
84     printf("%lld\n",ans);
85     return 0;
86 }
a

 

2016-09-26 16:11:26

 

 

posted @ 2016-09-26 13:51  konjak魔芋  阅读(555)  评论(0编辑  收藏  举报