【BZOJ】【3240】【NOI2013】矩阵游戏

十进制快速幂+矩阵乘法+常数优化



  听说这题还可以强行算出来递推式……然后乘乘除除算出来……

  然而蒟蒻选择了一个比较暴力的做法= =

  我们发现这个递推的过程是线性的,所以可以用矩阵乘法来表示,$x=a*x+b$这样一个递推式我们可以这样表示:$$\begin{bmatrix} x& 1 \end{bmatrix} * \begin{bmatrix} a& 0 \\ b& 1 \end{bmatrix} $$

  那么我们可以令$s_1$表示×a+b,$s_2$表示×c+d,那么我们有$$ans=v * ( ({s_1}^{n-1}*s_2)^{m-1} * {s_1}^{n-1} )$$

  然而直接算我给TLE了……

  

  下面说一下常数优化:

  我们注意到矩阵乘法的时候有:$$\begin{bmatrix} a& 0 \\ b& 1 \end{bmatrix} * \begin{bmatrix} c& 0 \\ d& 1 \end{bmatrix} = \begin{bmatrix} a*c& 0 \\ a*d+b& 1 \end{bmatrix}$$

  也就是说:第二列的0和1是一直不动的……那么我们可以将大部分$O(n^3)$的矩阵乘法过程优化到$O(n^2)$。

  这里我们${s_1}^{n-1}$出现了两次,那么我们可以用一个中间变量先存下来,可以减少一次运算(毕竟整个算法的主要部分就是在算这几个power)

 1 /**************************************************************
 2     Problem: 3240
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:7980 ms
 7     Memory:3232 kb
 8 ****************************************************************/
 9
10 //BZOJ 3240
11 #include<vector>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 #define pb push_back
21 using namespace std;
22 inline int getint(){
23     int v=0,sign=1; char ch=getchar();
24     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
25     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
26     return v*sign;
27 }
28 const int N=1e6+10,INF=~0u>>2,P=1e9+7;
29 typedef long long LL;
30 /******************tamplate*********************/
31
32 struct Matrix{
33     int v[2][2];
34     Matrix(int x=0){F(i,0,1)F(j,0,1)if(i==j)v[i][j]=x;else v[i][j]=0;}
35     int* operator [] (int x){return v[x];}
36 }s1,s2,v;
37 inline Matrix operator * (Matrix a,Matrix b){
38     Matrix c;
39     if (a[0][1]==0 && a[1][1]==1 && b[0][1]==0 && b[1][1]==1){
40         c[0][0]=(LL)a[0][0]*b[0][0]%P;
41         c[0][1]=0;
42         c[1][0]=((LL)a[0][0]*b[1][0]+(LL)a[1][0])%P;
43         c[1][1]=1;
44         return c;
45     }
46     F(k,0,1) F(i,0,1) F(j,0,1)
47         c[i][j]=((LL)c[i][j]+(LL)a[i][k]*b[k][j]%P)%P;
48     return c;
49 }
50 inline Matrix Pow(Matrix a,int b){
51     Matrix c(1);
52     F(i,1,b) c=c*a;
53     return c;
54 }
55 inline Matrix Power(Matrix a,char* s){
56     Matrix r(1); int l=strlen(s);
57     D(i,l-1,0){
58         if (s[i]-‘0‘) r=r*Pow(a,s[i]-‘0‘);
59         a=Pow(a,10);
60     }
61     return r;
62 }
63 char n[N],m[N];
64 int main(){
65 #ifndef ONLINE_JUDGE
66     freopen("3240.in","r",stdin);
67     freopen("3240.out","w",stdout);
68 #endif
69     scanf("%s",n); scanf("%s",m);
70     int l1=strlen(n)-1;
71     while(n[l1]==‘0‘) n[l1--]=‘9‘;
72     n[l1]--;
73     l1=strlen(m)-1;
74     while(m[l1]==‘0‘) m[l1--]=‘9‘;
75     m[l1]--;
76 //  printf("%s %s\n",n,m);
77     int a,b,c,d;
78     a=getint(); b=getint(); c=getint(); d=getint();
79     v[0][0]=v[0][1]=1; v[1][0]=v[1][1]=0;
80     s1[0][0]=a; s1[0][1]=0; s1[1][0]=b; s1[1][1]=1;
81     s2[0][0]=c; s2[0][1]=0; s2[1][0]=d; s2[1][1]=1;
82     Matrix s3=Power(s1,m);
83     v=v*(Power(s3*s2,n)*s3);
84     printf("%d\n",v[0][0]);
85     return 0;
86 }

3240: [Noi2013]矩阵游戏

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 890  Solved: 390
[Submit][Status][Discuss]

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

1<=N,M<=10^1000 000,a<=a,b,c,d<=10^9

Source

[Submit][Status][Discuss]

时间: 2024-11-05 02:04:50

【BZOJ】【3240】【NOI2013】矩阵游戏的相关文章

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

3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式: F[1][1]=1F[i,j]=a*F[i][j-1]+

BZOJ 3240 [Noi2013] 矩阵游戏 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24594825 [原题] 3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 336  Solved: 158 [Submit][Status] Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质

bzoj 3240: [Noi2013]矩阵游戏

Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式: F[1][1]=1 F[i,j]=aF[i][j-1]+b (j!=1) F[i,1]=cF[i-1][m]+d (i!=1) 递推式中a,b,c,d都是给定的常数. 现在婷婷想知道F[n][m]的值是多少,请你帮助她.由于最终结果可能很大,你只需要输出F[

3240: [Noi2013]矩阵游戏

Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式: F[1][1]=1F[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

bzoj 1059: [ZJOI2007]矩阵游戏 二分图匹配

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1891  Solved: 919[Submit][Status] Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵

bzoj 1059: [ZJOI2007]矩阵游戏 [二分图][二分图最大匹配]

Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵的任意行列,交换这两列(即交换 对应格子的颜色)游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑 色.对于某些关卡,小Q百思不得其解,以致他开始怀疑这些关卡是不是根

BZOJ P1059 [ZJOI2007]矩阵游戏——solution

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4604  Solved: 2211[Submit][Status][Discuss] Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜

【bzoj3240】 Noi2013—矩阵游戏

http://www.lydsy.com/JudgeOnline/problem.php?id=3240 (题目链接) 题意 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) 求解F[n][m],a,b,c,d为常数. Solution 原来费马小定理对于矩阵乘法同样适用..设a为一矩阵,p为质数则: 正好这里的模数1000000007为质数,那么把n,m模上(p-1)后进行矩阵快速幂即可.用来优化的矩阵很好构造,

BZOJ 1059 [ZJOI2007]矩阵游戏

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1059 题意:给定一个n * n的01矩阵,可以任意交换两行或两列的数字,问是否能调整出一个局面,使得矩阵的主对角线(左上角到右下角的连线)上都是1.n≤200. 题解: 由于每次可以变化一些元素为1的点的行号与列号,但是其相对位置是不变的,也就是说对于(i,j)的元素,经过变换之后是(ai,bj),{an}和{bn}是1-n的排列,所以我们可以抛弃这些点的行号与列号来分析他们的相对关系. 目

bzoj3240: [Noi2013]矩阵游戏

Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式: F[1][1]=1F[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