题目要领:
1,矩阵的快速幂
2.由于相乘一次元素值就很大,且对m取模的话取模时机不影响所以每次都取
3.令 B= [
[A A]
[0 I]
]
则 B^k = [
[A^k A ...
A^k]
[0
I ]
]
则矩阵B的k次方的有上角即为答案。
- #include
- #include
- using namespace std;
- #define MAXV 70
- typedef struct{
- int r,c; //c行r列
- int mat[MAXV][MAXV];
- }Matrix;
- Matrix ans,cnt;
- int n,k,m;
- void Input(){
- int i,j;
- memset(cnt.mat,0,sizeof(cnt.mat));
- memset(ans.mat,0,sizeof(ans.mat));
- for(i=0;i
- for(j=0;j
- scanf("%d",&cnt.mat[i][j]);
- }
- for(i=0;i
- cnt.mat[i+n][i+n]=cnt.mat[i][i+n]=1;
- ans.mat[i][i]=ans.mat[i+n][i+n]=1;
- }
- cnt.c=cnt.r=2*n;
- ans.c=ans.r=2*n;
- }
- Matrix MatrixMul(Matrix x,Matrix y){ //矩阵乘法
- Matrix t;
- int i,j,v;
- memset(t.mat,0,sizeof(t.mat));
- t.c=x.c;
- t.r=y.r;
- for(i=0;i
- for(j=0;j
- for(v=0;v
- t.mat[i][j]+=((x.mat[i][v]*y.mat[v][j])%m);
- t.mat[i][j]=t.mat[i][j]%m;
- }
- return t;
- }
- void Binary(){
- //二分快速幂
- k++;
- while(k){
- if(k & 1) ans=MatrixMul(ans,cnt);
- cnt=MatrixMul(cnt,cnt);
- k=k>>1;
- }
- }
- void Output(){
- int i,j;
- for(i=0;i
- for(j=0;j
- if(i!=j)
- printf("%d ",ans.mat[i][j+n]);
- else
- printf("%d ",ans.mat[i][j+n]-1);
- printf("\n");
- }
- }
- int main(){
- while(~scanf("%d%d%d",&n,&k,&m)){
- Input();
- Binary();
- Output();
- }
- return 0;
- }