码迷,mamicode.com
首页 > 其他好文 > 详细

【矩阵乘法】OpenJ_POJ - C17F - A Simple Math Problem

时间:2017-07-18 22:14:14      阅读:436      评论:0      收藏:0      [点我收藏+]

标签:long   const   turn   fine   type   mod   poj   部分   sig   

算(7+4*sqrt(3))^n的整数部分(mod 1e9+7)。

容易想到矩乘快速幂,但是怎么算整数部分呢?

(7+4*sqrt(3))^n一定可以写成a+b*sqrt(3),同理(7-4*sqrt(3))^n一定可以写成a-b*sqrt(3),于是,

(7+4*sqrt(3))^n

= (7+4*sqrt(3))^n + (7-4*sqrt(3))^n - (7-4*sqrt(3))^n

= 2*a - (7-4*sqrt(3))^n/*必然小于1*/

所以其整数部分 = 2*a - 1

#include<vector>
#include<cstdio>
using namespace std;
typedef long long ll;
#define MOD 1000000007ll
typedef vector<ll> vec;
typedef vector<vec> mat;
mat I;
mat operator * (const mat &a,const mat &b){
	mat c(a.size(),vec(b[0].size()));
	for(int i=0;i<a.size();++i){
		for(int k=0;k<b.size();++k){
			for(int j=0;j<b[0].size();++j){
				c[i][j]=(c[i][j]+a[i][k]*b[k][j]%MOD)%MOD;
			}
		}
	}
	return c;
}
mat Quick_Pow(mat a,ll p){
	if(!p){
		return I;
	}
	mat res=Quick_Pow(a,p>>1);
	res=res*res;
	if(p&1ll){
		res=res*a;
	}
	return res;
}
int T,n;
int main(){
//	freopen("f.in","r",stdin);
	I.assign(2,vec(2));
	for(int i=0;i<2;++i){
		for(int j=0;j<2;++j){
			if(i==j){
				I[i][j]=1;
			}
			else{
				I[i][j]=0;
			}
		}
	}
	mat A(2,vec(2));
	A[0][0]=7; A[0][1]=12;
	A[1][0]=4; A[1][1]=7;
	mat B(2,vec(1));
	B[0][0]=1;
	B[1][0]=0;
	scanf("%d",&T);
	for(;T;--T){
		scanf("%d",&n);
		printf("%lld\n",((Quick_Pow(A,n)*B)[0][0]*2ll%MOD+MOD-1ll)%MOD);
	}
	return 0;
}

【矩阵乘法】OpenJ_POJ - C17F - A Simple Math Problem

标签:long   const   turn   fine   type   mod   poj   部分   sig   

原文地址:http://www.cnblogs.com/autsky-jadek/p/7202801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!