HDU 2256 Problem of Precision(矩阵快速幂)
Posted lalalatianlalu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2256 Problem of Precision(矩阵快速幂)相关的知识,希望对你有一定的参考价值。
题目:就是求(sqrt(2)+sqrt(3))^(2*n)向下取整然后在MOD1024
思路:这个题挺有意思,但是这个题我觉得只能这样了,因为这个题可以做是因为这个题目限制的很死,我们把(sqrt(2)+sqrt(3))转化为(5+2*sqrt(6))^n
设Sn=An+bn,An=(5+2*sqrt(6))^n,Bn=(5-2*sqrt(6))^n,可以发现Bn是小于1的,那我们最后的答案就是Sn-1取模
然后我们构造Sn*((5+2*sqrt(6))+(5-2*sqrt(6))),继续化简就会得到Sn*10=Sn+1-Sn-1,然后矩阵快速幂就可以 了
代码:
#include <cstdio> using namespace std; typedef long long LL; const int MOD=1024; ///使用前要先对r,c赋值 struct mat{ long long a[30][30]; int r,c; mat operator *(const mat &b)const{ mat ret; for (int i=0;i<r;i++){ for (int j=0;j<b.c;j++){ ret.a[i][j]=0; for (int k=0;k<c;k++) ret.a[i][j]+=a[i][k]*b.a[k][j],ret.a[i][j]%=MOD; } } ret.r=r; ret.c=b.c; return ret; } void init_unit(int x) { r=c=x; for(int i=0;i<r;i++){ for(int j=0;j<c;j++){ if(i==j)a[i][j]=1; else a[i][j]=0; } } } }unit; mat qmod(mat p,LL n){ unit.init_unit(p.c); mat ans=unit; while(n){ if(n&1)ans=p*ans; p=p*p; n>>=1; } return ans; } int main() { int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); mat A; A.r=2;A.c=2; A.a[0][0]=10;A.a[0][1]=-1; A.a[1][0]=1;A.a[1][1]=0; mat B; B.r=B.c=2; B.a[0][0]=10; B.a[1][0]=2; mat ans; ans.r=ans.c=2; ans=qmod(A,n-1); ans=ans*B; printf("%lld ",(ans.a[0][0]+MOD-1)%MOD); } return 0; }
以上是关于HDU 2256 Problem of Precision(矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章
HDU2256-Problem of Precision(矩阵构造+高速幂)
hdu-2256 Problem of Precision---矩阵快速幂+数学技巧
HDU 2256 Problem of Precision 数论矩阵快速幂