当前位置:   article > 正文

hdu 6395 (分块矩阵快速幂)_hdu - 6395

hdu - 6395

http://acm.hdu.edu.cn/showproblem.php?pid=6395

解题思路:p/n在一些区间内是相同的,找出这些区间用矩阵快速幂即可,区间右端点可以二分找也可以

//int j=P/i==0?n:min(n,P/(P/i));这样找,目前还不知道为什么可以这样0(1)的找。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. #define LL long long
  6. const LL mod =1e9+7;
  7. int A,B,C,D,P,n;
  8. struct node
  9. {
  10. LL a[4][4];
  11. node()
  12. {
  13. memset(a,0,sizeof(a));
  14. }
  15. };
  16. node operator *(node x,node y)
  17. {
  18. node tmp;
  19. for(int i=1;i<=3;i++)
  20. {
  21. for(int j=1;j<=3;j++)
  22. {
  23. for(int k=1;k<=3;k++)
  24. {
  25. tmp.a[i][j]=(tmp.a[i][j]+(x.a[i][k]*y.a[k][j])%mod)%mod;
  26. }
  27. }
  28. }
  29. return tmp;
  30. }
  31. void Print(node t)
  32. {
  33. for(int i=1;i<=3;i++)
  34. {
  35. for(int j=1;j<=3;j++)
  36. {
  37. cout<<t.a[i][j]<<" ";
  38. }
  39. cout<<endl;
  40. }
  41. }
  42. node qpow(node tmp,int k)
  43. {
  44. node t;
  45. t.a[1][1]=D,t.a[1][2]=1;
  46. t.a[2][1]=C,t.a[3][1]=1;
  47. t.a[3][3]=1,t.a[3][2]=0;
  48. while(k)
  49. {
  50. if(k&1)
  51. tmp=tmp*t;
  52. t=t*t;
  53. k>>=1;
  54. }
  55. return tmp;
  56. }
  57. int solve(int s)
  58. {
  59. int l=s;
  60. int r=n;
  61. int tmp=P/l;
  62. int cnt=33;
  63. while(cnt--)
  64. {
  65. //cout<<l<<" "<<r<<" "<<tmp<<endl;
  66. int m=(l+r)>>1;
  67. if((P/m)<tmp)
  68. {
  69. r=m-1;
  70. }
  71. else if((P/m)>tmp)l=m+1;
  72. else l=m;
  73. }
  74. return l;
  75. }
  76. int main()
  77. {
  78. int t;
  79. cin>>t;
  80. while(t--)
  81. {
  82. scanf("%d%d%d%d%d%d",&A,&B,&C,&D,&P,&n);
  83. LL f1=A;
  84. LL f2=B;
  85. if(n==1)
  86. {
  87. printf("%d\n",A);
  88. continue;
  89. }
  90. if(n==2)
  91. {
  92. printf("%d\n",B);
  93. continue;
  94. }
  95. for(int i=3;i<=n;)
  96. {
  97. //int j=P/i==0?n:min(n,P/(P/i));
  98. int j=solve(i);
  99. node tmp;
  100. tmp.a[1][1]=f2,tmp.a[1][2]=f1;
  101. tmp.a[1][3]=(P/i)*1LL;
  102. node kuai=qpow(tmp,j-i+1);
  103. f2=kuai.a[1][1],f1=kuai.a[1][2];
  104. i=j+1;
  105. }
  106. printf("%lld\n",f2);
  107. }
  108. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/941909
推荐阅读
相关标签
  

闽ICP备14008679号