poj3070

用二分法求矩阵幂

先把矩阵的2^x全算出来存入数组的第x位。然后读入n,从右至左遍历数组,能乘则乘,直到把n填满。

View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
using namespace std;

#define w 10000;

struct Pow2
{
int matrix[2][2];
int num;
} pow2[
50];

Pow2 mul(Pow2
&a, Pow2 &b)
{
Pow2 ret;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
ret.matrix[i][j]
= 0;
for (int k = 0; k < 2; k++)
{
ret.matrix[i][j]
+= a.matrix[i][k] * b.matrix[k][j] % w;
ret.matrix[i][j]
%= w;
}
}
return ret;
}

int work(int n)
{
if (n <= 1)
return n;
n
--;
Pow2 temp;
int i = 1;
while (n >= pow2[i].num)
i
++;
i
--;
temp
= pow2[i];
n
-= pow2[i].num;
while (n)
{
while (n < pow2[i].num)
i
--;
n
-= pow2[i].num;
temp
= mul(pow2[i], temp);
}
return temp.matrix[0][0];
}

int main()
{
int n;
//freopen("D:\\t.txt", "r", stdin);
pow2[1].matrix[0][0] = 1;
pow2[
1].matrix[1][0] = 1;
pow2[
1].matrix[0][1] = 1;
pow2[
1].matrix[1][1] = 0;
pow2[
1].num = 1;
for (int i = 1; i <= 40; i++)
pow2[i
+ 1] = mul(pow2[i], pow2[i]);
for (int i = 1; i <= 40; i++)
pow2[i
+ 1].num = pow2[i].num * 2;
while (scanf("%d", &n) != EOF && n != -1)
printf(
"%d\n", work(n));
return 0;
}
posted @ 2011-03-04 09:55  金海峰  阅读(496)  评论(0编辑  收藏  举报