矩阵快速幂入门题
#include<iostream>
#include<cstdio>
using namespace std;
int n,a[2][2],b[2][2];
void mul(int a[2][2],int b[2][2],int ans[2][2])
{
int t[2][2];
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
t[i][j]=0;
for(int k=0;k<2;k++)
t[i][j]=(t[i][j]+a[i][k]*b[k][j])%10000;
//就是矩阵相乘的公式(发现公式最内的循环就k变)
}
memcpy(ans,t,sizeof(t));
}
int main()
{
//cout<<sizeof(a)<<endl;
while(scanf("%d",&n))
{
if(n==-1)return 0;
a[0][0]=a[0][1]=a[1][0]=1;a[1][1]=0;
b[0][0]=b[1][1]=1;
b[1][0]=b[0][1]=0;
/*
F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. (where 0 ≤ n ≤ 1,000,000,000).
故用矩阵
[fn+1 fn] [1 1]^n
[fn fn-1]=[1 0] .要是题目不告诉我=这个... --神奇(★精华在这)
模拟一下就发现其实是有道理的每次乘以{(1,1)(1,0)}矩阵得到{(fn+1+fn,fn+1),(fn+1,fn)}发现每次向后移动了一个斐波那契数列
*/
while(n)
{
if(n&1)mul(a,b,b);
n>>=1;
mul(a,a,a);
}
printf("%d\n",b[1][0]);
}
}
//腰好也不需要这样扭吧...开始还以为是什么-- (回溯思想--还联系到了奇偶性,不错的解法)
#include <iostream>
#include <string.h>
using namespace std;
int Fibonacci[2][2]={1,1,1,0};
void matrix_pow(int c[2][2],int n){
//4进来4 2 1深入 1 2 (2*2) 4回溯
//4进来5 2 1深入 1 2 (2*2+1) 5回溯
//6进来6 3 1深入 1 3 (3*3) 6回溯
int i,j,k;
if(n == 1){
memcpy(c,Fibonacci,4 * sizeof(int)); return;
}
int tmp[2][2];
matrix_pow(tmp,n/2);
for(i = 0;i < 2;i++)
for(j = 0;j < 2;j++){
c[i][j] = 0;
for(k = 0;k < 2;k++)
c[i][j] = (c[i][j] + tmp[i][k] * tmp[k][j]) % 10000;
} //tmp^2
if(n & 1){ //指数为奇数
memcpy(tmp,c,4 * sizeof(int)); //tmp=tmp^2
for(i = 0;i < 2;i++)
for(j = 0;j < 2;j++){
c[i][j] = 0;
for(k = 0;k < 2;k++)
c[i][j] = (c[i][j] + tmp[i][k] * Fibonacci[k][j]) % 10000;
}
}
}
int main(){
int n;
while(cin>>n && n >= 0){
if(n == 0){
cout<<0<<endl;continue;
}
if(n == 1 || n == 2){
cout<<1<<endl; continue;
}
n-=2;//
int c[2][2];
matrix_pow(c,n);
cout<<(c[0][0] + c[1][0]) % 10000<<endl;
}
return 0;
}