#include <iostream>
#include <assert.h>
#include <algorithm>
#include <time.h>
using namespace std;
typedef long long UINT;
// [ m_x00 m_x01 ]
// [ m_x10 m_x11 ]
class Mat
{
public:
Mat():m_x00(0), m_x01(0), m_x10(0), m_x11(0){}
Mat(UINT x00, UINT x01,
UINT x10, UINT x11):
m_x00(x00), m_x01(x01),m_x10(x10),m_x11(x11){}
UINT m_x00;
UINT m_x01;
UINT m_x10;
UINT m_x11;
};
void Multi(const Mat &m1, const Mat &m2, Mat &out)
{
out.m_x00 = m1.m_x00 * m2.m_x00 + m1.m_x01 * m2.m_x10;
out.m_x01 = m1.m_x00 * m2.m_x01 + m1.m_x01 * m2.m_x11;
out.m_x10 = m1.m_x10 * m2.m_x00 + m1.m_x11 * m2.m_x10;
out.m_x11 = m1.m_x10 * m2.m_x01 + m1.m_x11 * m2.m_x11;
}
void mPow(Mat &m, int n)
{
if (n==1 || n==0)
{
m.m_x00=1;
m.m_x01=1;
m.m_x10=1;
m.m_x11=0;
return;
}
mPow(m,n>>1);
Mat tm=m;
Multi(tm,tm,m);
if (n%2!=0)
{
Mat one(1,1,1,0);
Mat tm=m;
Multi(tm,one,m);
}
}
UINT getFibo(int n)
{
Mat m;
mPow(m, n);
return m.m_x00;
}
int main()
{
UINT an[]={0,1,2,3,4,5,6,7,8,9,10};
//copy(an,an+11,ostream_iterator<int>(cout," "));
//cout<<endl;
int i;
//for (i=0; i<11; i++)
//{
// cout<<i<<" "<<getFibo(an[i]*4)<<endl;
//}
//cout<<endl;
long long fb[3004];
fb[0]=fb[1]=1;
//for (i=2; i<40; i++)
//{
// fb[i]=fb[i-1]+fb[i-2];
// cout<<i<<" "<<fb[i]<<endl;
//}
//cout<<endl;
// 计时
int N=100000;
long long n;
time_t ibegin,iend;
//
ibegin = clock();
while (N--)
{
n=getFibo(1000);
}
iend=clock();
cout<<"Mat time: "<<iend-ibegin<<endl;
cout<<n<<endl;
N=100000;
//
ibegin = clock();
while (N--)
{
for (i=2; i<1001; i++)
{
fb[i]=fb[i-1]+fb[i-2];
}
}
iend=clock();
cout<<"Linear time: "<<iend-ibegin<<endl;
cout<<fb[1000]<<endl;
return 0;
}
n小的时候,线性算法更省时,n上几千以后,logn算法就体现出优势了。