连分数

来源:互联网 发布:惠州惠阳区网络问政 编辑:程序博客网 时间:2024/04/30 08:26

连分数

分类: 数论 197人阅读 评论(0) 收藏 举报

对于连分数,我们可以表示为:



对于无理数,ai一定是无穷数列,反之,对于有理数,ai一定是有穷数列。

对于上式中的p与q,有递推式:




而对于sqrt(n)来说,ai中的首项为一个单独的整数,除了它后面的都会循环。


下面我们来分析一个关于连分数的题目。


题目:连分数


题意:给两个整数n和k,n<=10^6,k<=10^9,sqrt(n)可以表示为连分数,求满足数列到ak的结果。

分子分母对1000000007取余。


对于这个问题,当然是先求出数列ai,求这个直接倒啊倒。

关键是有了这个ai数列,如何求到第k位的结果。这个当然有循环节,然后在一个循环节内是可以先处理出结果。

然后再计算有多少个这样的循环节,这部分就可以快速幂,剩下的部分就直接multi暴力吧。


此过程中还有一个重要的点,就是:


怎么处理的?


在本题由于sqrt(n)的整数部分没有存进a数组,我们知道p1=a1,p2=a1a2+1,所以我们把上述矩阵表示为:


所以这样完全就解决问题了,如果是q,最后面那个矩阵应该是0,1


[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <string.h>  
  3. #include <stdio.h>  
  4. #include <algorithm>  
  5. #include <math.h>  
  6.   
  7. using namespace std;  
  8. typedef long long LL;  
  9. const int N=50005;  
  10. const double eps=1e-8;  
  11. const LL MOD=1000000007;  
  12.   
  13. LL a[N];  
  14. LL cnt;  
  15.   
  16. struct Matrix  
  17. {  
  18.     LL m[2][2];  
  19. };  
  20.   
  21. Matrix per={1,0,0,1};  
  22.   
  23. Matrix multi(Matrix a,Matrix b)  
  24. {  
  25.     int i,j,k;  
  26.     Matrix c;  
  27.     for(i=0;i<2;i++)  
  28.     {  
  29.         for(j=0;j<2;j++)  
  30.         {  
  31.             c.m[i][j]=0;  
  32.             for(k=0;k<2;k++)  
  33.                 c.m[i][j]+=a.m[i][k]%MOD*b.m[k][j]%MOD;  
  34.             c.m[i][j]%=MOD;  
  35.         }  
  36.     }  
  37.     return c;  
  38. }  
  39.   
  40. Matrix matrix_mod(Matrix a,LL k)  
  41. {  
  42.     Matrix p=a,ans=per;  
  43.     while(k)  
  44.     {  
  45.         if(k&1)  
  46.         {  
  47.             ans=multi(ans,p);  
  48.             k--;  
  49.         }  
  50.         k>>=1;  
  51.         p=multi(p,p);  
  52.     }  
  53.     return ans;  
  54. }  
  55.   
  56. LL gcd(LL a,LL b)  
  57. {  
  58.     return b? gcd(b,a%b):a;  
  59. }  
  60.   
  61. void Loop(LL n)  
  62. {  
  63.     double k=sqrt(n*1.0);  
  64.     LL q=1,p=(LL)k,tmp=1;  
  65.     double first=k-p;  
  66.     while(1)  
  67.     {  
  68.         tmp=q;  
  69.         q=n-p*p;  
  70.         LL G=gcd(tmp,q);  
  71.         q/=G;tmp/=G;  
  72.         k=(sqrt(1.0*n)+p)*tmp/q;  
  73.         a[cnt++]=(LL)k;  
  74.         p=abs(p-a[cnt-1]*q);  
  75.         if(fabs(k-a[cnt-1]-first)<eps) break;  
  76.     }  
  77. }  
  78.   
  79. int main()  
  80. {  
  81.     LL n,k,p,q,x,y;  
  82.     Matrix ans1,ans2,ans3,A;  
  83.     while(cin>>n>>k)  
  84.     {  
  85.         k++;  
  86.         cnt=0;  
  87.         Loop(n);  
  88.         ans1=ans2=per;  
  89.         A.m[0][1]=1;  
  90.         A.m[1][0]=1;  
  91.         A.m[1][1]=0;  
  92.         for(int i=cnt-1;i>=0;i--)  
  93.         {  
  94.             A.m[0][0]=a[i];  
  95.             ans1=multi(ans1,A);  
  96.         }  
  97.         x=k%cnt;  
  98.         y=k/cnt;  
  99.         ans1=matrix_mod(ans1,y);  
  100.         for(int i=x-1;i>=0;i--)  
  101.         {  
  102.             A.m[0][0]=a[i];  
  103.             ans2=multi(ans2,A);  
  104.         }  
  105.         ans3=multi(ans2,ans1);  
  106.         p=ans3.m[1][0]%MOD;  
  107.         q=ans3.m[1][1]%MOD;  
  108.         LL tmp=q; q=p;  
  109.         p=((LL)sqrt(n*1.0)%MOD*p%MOD+tmp)%MOD;  
  110.         cout<<p<<"/"<<q<<endl;  
  111.     }  
  112.     return 0;  
  113. }  
原创粉丝点击