Problem of Precision(矩阵快速幂(推理))
2017-05-31 08:21
148 查看
【题目来源】:https://vjudge.net/problem/HDU-2256
【题意】
题意不再解释,相必都可以看得懂。。
【思路】
起初,我能想到的是找前一项和后一项的关系,直接通过矩阵快速幂求出来,我找到的关系是:前一项的a到下一项就变成了a²+b²,而b变成了2ab,就这样想了想,写出了关系矩阵:
接下来要考虑double的事,上网查了下double怎么取余,答案是增大一定的倍数,取余,然后再除以一定的倍数,看到这里,就自动否决了、、
接下来,看了博客,发现是另外一种思路。
找到对应的关系:
假设Fn=an+bn(sqrt(6)),Fn-1=an-1+bn-1(sqrt(6))
那么Fn=(5+2(sqrt(6)))*Fn-1
所以an+bn(sqrt(6))=(5+2(sqrt(6)))*(an-1+bn-1(sqrt(6)))
整理得:
an=5an-1+12bn-1;
bn=(2an-1+5bn-1)*sqrt(6);
根据矩阵乘法,得到一个这样的矩阵关系式:
但是,最后的值还是要double的,所以好像相比我那种,只是把中间过程的double省略了,但是接着看的时候,明白了:
(an+bn(sqrt(6)))²+(an-bn(sqrt(6)))²==2an
但是呢5-2(sqrt(6))≈≈0,所以(5-2(sqrt(6)))ⁿ≈≈0;
so (an+bn(sqrt(6)))≈2an;
又因为左边取的是下限,所以2an-1。
所以结果就是2an-1。
【代码】
【题意】
题意不再解释,相必都可以看得懂。。
【思路】
起初,我能想到的是找前一项和后一项的关系,直接通过矩阵快速幂求出来,我找到的关系是:前一项的a到下一项就变成了a²+b²,而b变成了2ab,就这样想了想,写出了关系矩阵:
接下来要考虑double的事,上网查了下double怎么取余,答案是增大一定的倍数,取余,然后再除以一定的倍数,看到这里,就自动否决了、、
接下来,看了博客,发现是另外一种思路。
找到对应的关系:
假设Fn=an+bn(sqrt(6)),Fn-1=an-1+bn-1(sqrt(6))
那么Fn=(5+2(sqrt(6)))*Fn-1
所以an+bn(sqrt(6))=(5+2(sqrt(6)))*(an-1+bn-1(sqrt(6)))
整理得:
an=5an-1+12bn-1;
bn=(2an-1+5bn-1)*sqrt(6);
根据矩阵乘法,得到一个这样的矩阵关系式:
但是,最后的值还是要double的,所以好像相比我那种,只是把中间过程的double省略了,但是接着看的时候,明白了:
(an+bn(sqrt(6)))²+(an-bn(sqrt(6)))²==2an
但是呢5-2(sqrt(6))≈≈0,所以(5-2(sqrt(6)))ⁿ≈≈0;
so (an+bn(sqrt(6)))≈2an;
又因为左边取的是下限,所以2an-1。
所以结果就是2an-1。
【代码】
#include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<limits.h> #include<algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int mod=1024; const double esp=1e-5; typedef unsigned long long ll; typedef long long LL; int n; struct mat { int a[3][3]; }base; mat operator*(mat s,mat t) { mat r; mem(r.a,0); for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int p=1;p<=2;p++) { r.a[i][j]=r.a[i][j]+s.a[i][p]*t.a[p][j]; if(r.a[i][j]>=mod) r.a[i][j]%=mod; } return r; } void print(mat s) { printf("%d %d\n",s.a[1][1],s.a[1][2]); printf("%d %d\n",s.a[2][1],s.a[2][2]); } void pow_mat(mat &ans) { mat base,temp; mem(base.a,0); base.a[1][1]=5; base.a[1][2]=2; base.a[2][1]=12; base.a[2][2]=5; mem(temp.a,0); for(int i=1;i<=2;i++) temp.a[i][i]=1; while(n) { if(n&1) temp=temp*base; //// print(base); base=base*base; // print(base); n>>=1; } ans=ans*temp; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); if(n==1) { printf("%d\n",9); continue; } n--; mat ans; mem(ans.a,0); ans.a[1][1]=5; ans.a[1][2]=2; pow_mat(ans); int x=(ans.a[1][1]*2-1)%mod; printf("%d\n",x); } }
相关文章推荐
- HDU 2256 Problem of Precision(矩阵快速幂 数论 )
- Problem of Precision(矩阵快速幂)
- hdu 2256 Problem of Precision -矩阵快速幂
- HDU 2256 Problem of Precision(矩阵快速幂)
- HDU 2256 Problem of Precision 数论矩阵快速幂
- hdu 2256 Problem of Precision(矩阵快速幂 推公式)
- HDU 2256 Problem of Precision (矩阵快速幂)
- hdoj 2256 Problem of Precision 【矩阵快速幂】【构建矩阵好题】
- Hdu 2256 Problem of Precision[矩阵快速幂 + 数学]
- HDU 2256 Problem of Precision(矩阵快速幂入门题)
- HDU 2256 Problem of Precision (矩阵快速幂+ 化简 +向下取整)
- hdu 2256 Problem of Precision 矩阵快速幂
- HDU 2256 Problem of Precision (矩阵快速幂)
- HDU 2256 Problem of Precision 解题报告(矩阵快速幂 + 构造)
- HDU - 2256 Problem of Precision 矩阵快速幂
- hdu 2256 Problem of Precision(矩阵快速幂,得出递推式有难度)
- HDU.2256 Problem of Precision (矩阵快速幂)
- hdu2256:Problem of Precision(矩阵快速幂+共轭)
- HDU 2256 Problem of Precision(矩阵快速幂)
- Kiki & Little Kiki 2(矩阵快速幂(推理))