10.17T6 矩阵快速幂

Description

【题目背景】 
  守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她传送到后面的监狱内查看,她比较懒,一般不查看完所有的监狱,只是从入口进入,然后再从出口出来就算完成任务了。 
【问题描述】 
  头脑并不发达的warden最近在思考一个问题,她的闪烁技能是可以升级的,k级的闪烁技能最多可以向前移动k个监狱,一共有n个监狱要视察,她从入口进去,一路上有n个监狱,而且不会往回走,当然她并不用每个监狱都视察,但是她最后一定要到第n个监狱里去,因为监狱的出口在那里,但是她并不一定要到第1个监狱。
  守望者warden现在想知道,她在拥有k级闪烁技能时视察n个监狱一共有多少种方案? 

Input

  第一行是闪烁技能的等级k(1<=k<=10)
  第二行是监狱的个数n(1<=n<=2^31-1)

Output

  由于方案个数会很多,所以输出它 mod 7777777后的结果就行了

Sample Input

2 4

Sample Output

5

Hint

  把监狱编号1 2 3 4,闪烁技能为2级,
  一共有5种方案
  →1→2→3→4
  →2→3→4
  →2→4
  →1→3→4
  →1→2→4

  小提示:建议用long long,否则可能会溢出
 
 
 
 
明显的矩阵快速幂,不过没有大小,套板子就可以了,现在终于能轻松手写快速幂了
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 struct matrix{
 6     long long a[11][11];
 7 };
 8 long long n,m;
 9 const long long mod=7777777;
10 matrix mul(matrix a,matrix b){
11     matrix ans;
12     memset(ans.a,0,sizeof ans.a);
13     for(long long k=1;k<=n;k++){
14         for(long long i=1;i<=n;i++){
15             for(long long j=1;j<=n;j++){
16                 ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
17             }
18         }
19     }
20     return ans;
21 }
22 int main(){
23     cin>>n>>m;
24     matrix base;
25     memset(base.a,0,sizeof base.a);
26     for(long long i=1;i<=n;i++)base.a[i][1]=1;
27     for(long long i=1;i<n;i++)base.a[i][i+1]=1;
28     matrix ans;
29     memset(ans.a,0,sizeof ans.a);
30     for(long long i=1;i<=n;i++)ans.a[i][i]=1;
31     for(;m;m>>=1){
32         if(m&1){
33             ans=mul(ans,base);
34         }
35         base=mul(base,base);
36     }        
37     cout<<ans.a[1][1];
38     return 0;
39 }

over

posted @ 2018-10-17 21:19  saionjisekai  阅读(54)  评论(0编辑  收藏  举报