矩阵快速二分求n次幂

http://ac.jobdu.com/problem.php?pid=1081      递推数列

同理Fibonacci数列也可以使用矩阵来求,二分求矩阵的n次幂可以达到O(N*lgN)的时间复杂度。。

(2^n)%k的问题也可以使用这个二分的方法来求解。。

#include<iostream>
#include<cstdio>
using namespace std;

struct Matrix
{
	int a[2][2];
};

Matrix E;

void InitE(int size)       //初始化单位矩阵
{
	for(int i=0;i<size;i++)
	{
		for(int j=0;j<size;j++)
			E.a[i][j]=(i==j);
	}
}
Matrix MatrixMul(Matrix a,Matrix b)     //两矩阵相乘   
{
	Matrix c;
	int i,j,k;
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;j++)
		{
			c.a[i][j]=0;
			for(k=0;k<2;k++)
			{
				c.a[i][j] += ((a.a[i][k]%10000)*(b.a[k][j]%10000));
				c.a[i][j]%=10000;
			}
		}
	}
	return c;
}
Matrix MatrixPow(Matrix a,int n)         //矩阵快速二分求n次幂
{
	Matrix t=E;
	while(n>0)
	{
		if(1&n)     //n是奇数
			t=MatrixMul(t,a);
		a=MatrixMul(a,a);
		n >>= 1;
	}
	return t;
}

int main(void)
{
	int a0,a1,p,q,k;
	Matrix matrix,m;
	InitE(2);
	while(scanf("%d %d %d %d %d",&a0,&a1,&p,&q,&k)!=EOF)
	{
		if(!k)        //这两个特殊情况当时未考虑,导致多次WA
			printf("%d\n",a0);
		else if(k==1)
			printf("%d\n",a1);
		else
		{
			matrix.a[0][0]=p;     //构造初始矩阵
			matrix.a[0][1]=q;
			matrix.a[1][0]=1;
			matrix.a[1][1]=0;
			m=MatrixPow(matrix,k-1);
			printf("%d\n",(m.a[0][0]*a1+m.a[0][1]*a0)%10000);
		}
	}
	return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=2035 快速二分求幂A^B

#include<iostream>
using namespace std;
#include<stdio.h>

inline int Pow(int x,int k,int mod)    //快速二分求幂x^k
{
	int ans=1;
	while(k)
	{
		if(k&1)
		{
			ans*=x;
			if(ans>=mod)
				ans%=mod;
		}
		x*=x;
		if(x>=mod)
			x%=mod;
		k>>=1;
	}
	return ans;
}

int main(void)
{
	int a,b;
	while(scanf("%d %d",&a,&b) && a && b)
	{
		printf("%d\n",Pow(a,b,1000));
	}
	return 0;
}


 

你可能感兴趣的:(c,Matrix)