题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=3240

3240: [Noi2013]矩阵游戏

Time Limit: 10 Sec  Memory Limit: 256 MB

Submit: 317  Solved: 152

[Submit][Status]

Description

婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用操心她怎样存储)。她生成的这个矩阵满足一个奇妙的性质:若用F[i][j]来表示矩阵中第i行第j列的元素。则F[i][j]满足以下的递推式:



F[1][1]=1

F[i,j]=a*F[i][j-1]+b (j!=1)

F[i,1]=c*F[i-1][m]+d (i!=1)

递推式中a,b,c,d都是给定的常数。



如今婷婷想知道F[n][m]的值是多少,请你帮助她。因为终于结果可能非常大,你仅仅须要输出F[n][m]除以1,000,000,007的余数。

Input

一行有六个整数n,m,a,b,c,d。意义如题所述

Output

包括一个整数,表示F[n][m]除以1,000,000,007的余数

Sample Input

3 4 1 3 2 6

Sample Output

85

HINT

例子中的矩阵为:



1 4 7 10



26 29 32 35



76 79 82 85

Source





解题思路:

十进制高速幂

须要优化常数,能够把矩阵优化到仅仅保存两个数。每次矩阵乘法时,仅仅需计算两次乘法即可了。大大加快了速度。

显然最后结果为A^m(BA^mF)^n 当中A(a,b,0,1)  B(c,d,0,1) F(1,0,0,1)

保存一个v1,v2. 矩阵乘法时 c.v1=a.v1*b.v1 c.v2=a.v1*b.v2+a.v2    (ta*(1,2)+tb=(ta*1,ta*2+tb))

代码:

  1. //#include<CSpreadSheet.h>
  2.  
  3. #include<iostream>
  4. #include<cmath>
  5. #include<cstdio>
  6. #include<sstream>
  7. #include<cstdlib>
  8. #include<string>
  9. #include<string.h>
  10. #include<cstring>
  11. #include<algorithm>
  12. #include<vector>
  13. #include<map>
  14. #include<set>
  15. #include<stack>
  16. #include<list>
  17. #include<queue>
  18. #include<ctime>
  19. #include<bitset>
  20. #include<cmath>
  21. #define eps 1e-6
  22. #define INF 0x3f3f3f3f
  23. #define PI acos(-1.0)
  24. //#define ll __int64
  25. #define ll long long
  26. #define lson l,m,(rt<<1)
  27. #define rson m+1,r,(rt<<1)|1
  28. #define MM 1000000007
  29. //#pragma comment(linker, "/STACK:1024000000,1024000000")
  30. using namespace std;
  31.  
  32. #define Maxn 1100000
  33.  
  34. char s1[Maxn],s2[Maxn];
  35. ll a,b,c,d;
  36.  
  37. void sub(char * cur)
  38. {
  39. int len=strlen(cur);
  40.  
  41. len--;
  42. if(cur[len]!='0')
  43. {
  44. cur[len]=cur[len]-1;
  45. return ;
  46. }
  47. cur[len]='9';
  48. len--;
  49.  
  50. while(len>=0&&cur[len]=='0')
  51. {
  52. cur[len]='9';
  53. len--;
  54. }
  55. cur[len]=cur[len]-1;
  56. }
  57. struct Mar
  58. {
  59. ll v1,v2;
  60.  
  61. void init(ll a,ll b)
  62. {
  63. v1=a;
  64. v2=b;
  65. }
  66. friend struct Mar operator * (const struct Mar &a,const struct Mar &b)
  67. {
  68.  
  69. Mar c;
  70.  
  71. c.v1=(a.v1*b.v1)%MM;
  72. c.v2=(a.v1*b.v2+a.v2)%MM;
  73.  
  74. return c;
  75.  
  76. }
  77.  
  78. };
  79.  
  80. Mar Pow(Mar aa,ll bb)
  81. {
  82. Mar c;
  83. c.init(1,0);
  84. //c.s[1][1]=1,c.s[2][2]=1;
  85.  
  86. while(bb)
  87. {
  88. if(bb&1)
  89. c=aa*c;
  90. bb>>=1;
  91. aa=aa*aa;
  92. }
  93. return c;
  94. }
  95. Mar T_Pow(Mar aa,char * cur)
  96. {
  97. Mar res;
  98. res.init(1,0);
  99.  
  100. int i=strlen(cur)-1;
  101. int j=0;
  102. while(cur[j]=='0')
  103. j++;
  104. while(i>=j)
  105. {
  106. res=Pow(aa,cur[i]-'0')*res;
  107. aa=Pow(aa,10);
  108. i--;
  109. }
  110. return res;
  111. }
  112.  
  113. int main()
  114. {
  115. //freopen("in.txt","r",stdin);
  116. //freopen("out.txt","w",stdout);
  117.  
  118. while(~scanf("%s%s",s1,s2))
  119. {
  120. scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
  121. sub(s1);
  122. //printf("%s\n",s1);
  123. sub(s2);
  124. //printf("%s\n",s2);
  125. // ll n=cal(s1),m=cal(s2);
  126.  
  127. Mar A;
  128. A.init(a,b);
  129. //A.s[1][1]=a,A.s[1][2]=b,A.s[2][2]=1;
  130. Mar B;
  131. B.init(c,d);
  132. //B.s[1][1]=c,B.s[1][2]=d,B.s[2][2]=1;
  133.  
  134. Mar C=T_Pow(A,s2);
  135. Mar D=B*C;
  136. D=T_Pow(D,s1);
  137. D=C*D;
  138.  
  139. printf("%lld\n",(D.v1+D.v2)%MM);
  140.  
  141. }
  142. return 0;
  143. }

解题思路:

能够暴力推出公式.费马小定理不适合于矩阵的次幂,a=c=1时,退化成等差数列。需特判,其余等比数列。这题这样做有问题。矩阵的次幂不能用费马小定理来降次,仅仅是这题有点特殊。

代码:

  1. //#include<CSpreadSheet.h>
  2.  
  3. #include<iostream>
  4. #include<cmath>
  5. #include<cstdio>
  6. #include<sstream>
  7. #include<cstdlib>
  8. #include<string>
  9. #include<string.h>
  10. #include<cstring>
  11. #include<algorithm>
  12. #include<vector>
  13. #include<map>
  14. #include<set>
  15. #include<stack>
  16. #include<list>
  17. #include<queue>
  18. #include<ctime>
  19. #include<bitset>
  20. #include<cmath>
  21. #define eps 1e-6
  22. #define INF 0x3f3f3f3f
  23. #define PI acos(-1.0)
  24. //#define ll __int64
  25. #define ll long long
  26. #define lson l,m,(rt<<1)
  27. #define rson m+1,r,(rt<<1)|1
  28. #define MM 1000000007
  29. //#pragma comment(linker, "/STACK:1024000000,1024000000")
  30. using namespace std;
  31.  
  32. #define Maxn 1100000
  33.  
  34. char s1[Maxn],s2[Maxn];
  35. ll a,b,c,d,M;
  36.  
  37. ll cal(char * s)
  38. {
  39. ll res=0;
  40. int i=0;
  41.  
  42. while(s[i])
  43. {
  44. res=(res*10+s[i]-'0')%M;
  45. i++;
  46. }
  47. return (res-1+M)%M;
  48.  
  49. }
  50.  
  51. struct Mar
  52. {
  53. ll s[3][3];
  54. int row,col;
  55.  
  56. void init(int a,int b)
  57. {
  58. row=a,col=b;
  59. memset(s,0,sizeof(s));
  60. }
  61.  
  62. };
  63. struct Mar operator * (const struct Mar &a,const struct Mar &b)
  64. {
  65. Mar c;
  66.  
  67. c.init(a.row,b.col);
  68.  
  69. for(int k=1;k<=a.col;k++)
  70. {
  71. for(int i=1;i<=a.row;i++)
  72. {
  73. if(!a.s[i][k])
  74. continue;
  75. for(int j=1;j<=b.col;j++)
  76. {
  77. if(!b.s[k][j])
  78. continue;
  79. c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j])%MM;
  80. }
  81. }
  82. }
  83. return c;
  84.  
  85. }
  86.  
  87. Mar Pow(Mar aa,ll bb)
  88. {
  89. Mar c;
  90. c.init(aa.row,aa.col);
  91. c.s[1][1]=1,c.s[2][2]=1;
  92.  
  93. while(bb)
  94. {
  95. if(bb&1)
  96. c=aa*c;
  97. bb>>=1;
  98. aa=aa*aa;
  99. }
  100. return c;
  101. }
  102.  
  103. int main()
  104. {
  105. //freopen("in.txt","r",stdin);
  106. //freopen("out.txt","w",stdout);
  107.  
  108. while(~scanf("%s%s",s1,s2))
  109. {
  110. scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
  111.  
  112. if(a==1&&c==1)
  113. M=MM;
  114. else
  115. M=MM-1;
  116. // M=MM-1;
  117. ll n=cal(s1),m=cal(s2);
  118.  
  119. Mar A;
  120. A.init(2,2);
  121. A.s[1][1]=a,A.s[1][2]=b,A.s[2][2]=1;
  122.  
  123. Mar B;
  124. B.init(2,2);
  125. B.s[1][1]=c,B.s[1][2]=d,B.s[2][2]=1;
  126.  
  127. Mar C=Pow(A,m);
  128. Mar D=B*C;
  129. D=Pow(D,n);
  130. D=C*D;
  131.  
  132. printf("%lld\n",(D.s[1][1]+D.s[1][2])%MM);
  133.  
  134. }
  135. return 0;
  136. }

(十进制高速幂+矩阵优化)BZOJ 3240 3240: [Noi2013]矩阵游戏的更多相关文章

  1. bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

  2. 高速幂 POW优化

    #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h&g ...

  3. hdu 5411 CRB and Puzzle 矩阵高速幂

    链接 题解链接:http://www.cygmasot.com/index.php/2015/08/20/hdu_5411/ 给定n个点 常数m 以下n行第i行第一个数字表示i点的出边数.后面给出这些 ...

  4. ZOJ 3690 &amp; HDU 3658 (矩阵高速幂+公式递推)

    ZOJ 3690 题意: 有n个人和m个数和一个k,如今每一个人能够选择一个数.假设相邻的两个人选择同样的数.那么这个数要大于k 求选择方案数. 思路: 打表推了非常久的公式都没推出来什么可行解,好不 ...

  5. $[TJOI2017]$ 可乐 矩阵优化$dp$

    \(Sol\) 设\(f_i\)为到第\(i\)秒的方案数,显然\(f_i=\)在第\(i\)秒前爆炸的方案数+在第\(i\)秒爆炸的方案数+在第\(i\)秒停下的方案数+在第\(i\)秒走向下一个城 ...

  6. bzoj 3240 矩阵乘法+十进制快速幂

    首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b, 那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)* ...

  7. BZOJ 3240 [Noi2013]矩阵游戏 ——费马小定理 快速幂

    发现是一个快速幂,然而过不去. 怎么办呢? 1.十进制快速幂,可以用来练习卡时. 2.费马小定理,如果需要乘方的地方,可以先%(p-1)再计算,其他地方需要%p,所以需要保存两个数. 然后就是分类讨论 ...

  8. BZOJ 3240: [Noi2013]矩阵游戏

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1586  Solved: 698[Submit][Status ...

  9. BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec   Memory Limit: 256 MB Submit: 123   Solved: 73 [ Submit][ St ...

随机推荐

  1. 谷歌浏览器(chrome) —— 扩展应用程序

    工具的使用--谷歌浏览器(chrome) (二) 1. 设置和下载方法 右上角菜单按钮 ⇒ 更多工具(more tools) ⇒ 扩展(Extensions) 打开该页面之后,会首先进入扩展(已安装应 ...

  2. global cache cr request

    当一个进程访问需要一个或者多个块时,它会首先检查自己的CACHE是否存在该块,如果发现没有,就会先通过global cache赋予这些块 共享访问的权限,然后再访问.假如,通过global cache ...

  3. 在Spring Boot中使用Spring-data-jpa实现分页查询

    转自:https://www.cnblogs.com/sandea/p/8275890.html 在我们平时的工作中,查询列表在我们的系统中基本随处可见,那么我们如何使用jpa进行多条件查询以及查询列 ...

  4. Spring整合JUnit4测试使用注解引入多个配置文件

    转自:https://kanpiaoxue.iteye.com/blog/2151903 我们使用spring写junit单测的时候,有的时候我们的spring配置文件只有一个.我们在类的注释上面会这 ...

  5. [专辑] 也晒晒我的RBAC系统 ——行一山人的博客

    也晒晒我的RBAC系统(一):概述 也晒晒我的RBAC系统(二):系统实现原理简介 也晒晒我的RBAC系统(三):后台管理程序源码及使用演示 也晒晒我的RBAC系统(四):框架源代码(超值奉献,请勿拍 ...

  6. Python环境设置-zlib not available

    今天在Linux中安Python3的时候,出现了一个错误:zipimport.ZipImportError: can‘t decompress data; zlib not available 网上找 ...

  7. python课程设计笔记(三)turtle绘图库(海龟库)

    实例:绘制一条蟒蛇 #turtle:绘图库(海龟库) import turtle turtle.setup(650,350,200,200) turtle.penup() turtle.fd(-250 ...

  8. Java中从控制台输入数据的几种常用方法(转转)

    原文博客地址:https://www.cnblogs.com/SzBlog/p/5404246.html 一.使用标准输入串System.in  //System.in.read()一次只读入一个字节 ...

  9. SqlServer动态变换库名

    declare @tname varchar(20),@num intset @tname='Players_Log_L10001'declare @sql Nvarchar(1000)=N'sele ...

  10. JS 输名字随机弹出

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...