http://acm.hdu.edu.cn/showproblem.php?pid=2256&&构造矩阵求值

#include<iostream>
#include<string.h>
#include<algorithm>
#define N 1024
using namespace std;
typedef long long L;
typedef struct str
{ L  s[2][2];//注意数据范围
}Node;
Node a,b;
Node ceil(Node p,Node q)
{  Node c;
  memset(c.s,0,sizeof(c.s));
  for(int i=0;i<2;++i)
	  for(int j=0;j<2;++j)
		  for(int t=0;t<2;++t)
			  c.s[i][j]=(c.s[i][j]+p.s[i][t]*q.s[t][j])%N;
   return c;
}
Node doit(int k)
{ Node p=a,q=b;
   while(k)
   { if(1&k) p=ceil(p,q);
      q=ceil(q,q);
	  k=k>>1;
   }
   return p;
}
int main()
{ 
	int T;
	scanf("%d",&T);
	while(T--)
	{   a.s[0][0]=a.s[1][1]=1;
	    a.s[0][1]=a.s[1][0]=0;
		b.s[0][0]=b.s[1][1]=5;
		b.s[0][1]=12;b.s[1][0]=2;
		int n;
		 scanf("%d",&n);
			 if(n==1)
			 { printf("9\n");
			   continue;
			 }
			 n--;
			 Node c=doit(n);
			 int sum=(5*c.s[0][0]+2*c.s[0][1])%N;
			 printf("%d\n",(2*sum-1)%N);//注意结果是对1024取余
	}return 0;
}
/*
思路:构造矩阵,然后进行矩阵二分幂运算。
构造过程:
(sqrt(2)+sqrt(3))^2=5+2*sqrt(6);
(5+2*sqrt(6))^n=An+Bn*sqrt(6);
 Bn*sqrt(6)=An-(5-2*sqrt(6))^n;//因为此项等于(0.101...)^n 约等于0
(5+2*sqrt(6))^n=2*An-Bn*sqrt(6); 
An+Bn*sqrt(6)=(A(n-1)+B(n-1)*sqrt(6))*(5+2*sqrt(6))=(5*A(n-1)+12B(n-1))+(5*B(n-1)+2*A(n-1))*sqrt(6)
所以有:
An=5*A(n-1)+12B(n-1)
Bn=2*A(n-1)+5*B(n-1)
(5+2*sqrt(6))^n=An+Bn*sqrt(6)+(5-2*sqrt(6))^n=An-Bn*sqrt(6)=2An-(0.101...)^n
所以(5+2*sqrt(6))^n=2An-1
最后的答案ans=2An-1;
而矩阵为
| 5 12|
| 2  5|
*/


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