题目链接:

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))

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
//#define ll __int64
#define ll long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define MM 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 1100000 char s1[Maxn],s2[Maxn];
ll a,b,c,d; void sub(char * cur)
{
int len=strlen(cur); len--;
if(cur[len]!='0')
{
cur[len]=cur[len]-1;
return ;
}
cur[len]='9';
len--; while(len>=0&&cur[len]=='0')
{
cur[len]='9';
len--;
}
cur[len]=cur[len]-1;
}
struct Mar
{
ll v1,v2; void init(ll a,ll b)
{
v1=a;
v2=b;
}
friend struct Mar operator * (const struct Mar &a,const struct Mar &b)
{ Mar c; c.v1=(a.v1*b.v1)%MM;
c.v2=(a.v1*b.v2+a.v2)%MM; return c; } }; Mar Pow(Mar aa,ll bb)
{
Mar c;
c.init(1,0);
//c.s[1][1]=1,c.s[2][2]=1; while(bb)
{
if(bb&1)
c=aa*c;
bb>>=1;
aa=aa*aa;
}
return c;
}
Mar T_Pow(Mar aa,char * cur)
{
Mar res;
res.init(1,0); int i=strlen(cur)-1;
int j=0;
while(cur[j]=='0')
j++;
while(i>=j)
{
res=Pow(aa,cur[i]-'0')*res;
aa=Pow(aa,10);
i--;
}
return res;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout); while(~scanf("%s%s",s1,s2))
{
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
sub(s1);
//printf("%s\n",s1);
sub(s2);
//printf("%s\n",s2);
// ll n=cal(s1),m=cal(s2); Mar A;
A.init(a,b);
//A.s[1][1]=a,A.s[1][2]=b,A.s[2][2]=1;
Mar B;
B.init(c,d);
//B.s[1][1]=c,B.s[1][2]=d,B.s[2][2]=1; Mar C=T_Pow(A,s2);
Mar D=B*C;
D=T_Pow(D,s1);
D=C*D; printf("%lld\n",(D.v1+D.v2)%MM); }
return 0;
}

解题思路:

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

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
//#define ll __int64
#define ll long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define MM 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 1100000 char s1[Maxn],s2[Maxn];
ll a,b,c,d,M; ll cal(char * s)
{
ll res=0;
int i=0; while(s[i])
{
res=(res*10+s[i]-'0')%M;
i++;
}
return (res-1+M)%M; } struct Mar
{
ll s[3][3];
int row,col; void init(int a,int b)
{
row=a,col=b;
memset(s,0,sizeof(s));
} };
struct Mar operator * (const struct Mar &a,const struct Mar &b)
{
Mar c; c.init(a.row,b.col); for(int k=1;k<=a.col;k++)
{
for(int i=1;i<=a.row;i++)
{
if(!a.s[i][k])
continue;
for(int j=1;j<=b.col;j++)
{
if(!b.s[k][j])
continue;
c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j])%MM;
}
}
}
return c; } Mar Pow(Mar aa,ll bb)
{
Mar c;
c.init(aa.row,aa.col);
c.s[1][1]=1,c.s[2][2]=1; while(bb)
{
if(bb&1)
c=aa*c;
bb>>=1;
aa=aa*aa;
}
return c;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout); while(~scanf("%s%s",s1,s2))
{
scanf("%lld%lld%lld%lld",&a,&b,&c,&d); if(a==1&&c==1)
M=MM;
else
M=MM-1;
// M=MM-1;
ll n=cal(s1),m=cal(s2); Mar A;
A.init(2,2);
A.s[1][1]=a,A.s[1][2]=b,A.s[2][2]=1; Mar B;
B.init(2,2);
B.s[1][1]=c,B.s[1][2]=d,B.s[2][2]=1; Mar C=Pow(A,m);
Mar D=B*C;
D=Pow(D,n);
D=C*D; printf("%lld\n",(D.s[1][1]+D.s[1][2])%MM); }
return 0;
}

(十进制高速幂+矩阵优化)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. CodeForces 651A(水题)

    Friends are going to play console. They have two joysticks and only one charger for them. Initially ...

  2. 自定义数据类型 C++ 结构体类型 共同体类型 枚举类型 类类型{}

    一.结构体类型 结构体类型,共用体类型,枚举类型,类类型等统称为自定义类型(user-defined-type,UDT). 结构体相当于其他高级语言中的记录(record);例如: struct St ...

  3. 同一sql程序执行比数据库执行慢

    最近项目发现同一个sql在java端执行比在数据库执行慢很多,原因可能是程序的sql参数类型与数据库字段的类型不一致.

  4. 一个简单的js面试题

    在js群里看到有人发问,于是抱着练手的心态写了答了几个面试题,题目虽然不是太难,却很考验人的编程思维.汗颜,看了别人的答案后才发现自己好像笨了很多. 废话不说了 ,上代码. 1 要求 给一个数组的最后 ...

  5. Centos7 docker nginx容器搭建

    一.安装docker http://www.cnblogs.com/WJ--NET/p/8553807.html 二.创建Dockerfile #创建文件夹 mkdir centos_nginx cd ...

  6. APP开发过程的优惠券设计及流程

    在整个APP开发产品发展的整个周期中,运营活动必不可少,而发放优惠券已成为运营活动的一种基本形式,而关于优惠券设计的整体流程尤为重要.接下来,常州开发APP公司专家分享一下自己的经验,希望对大家有帮助 ...

  7. 四.Windows I/O模型之重叠IO(overlapped)模型

    1.适用于除Windows CE之外的各种Windows平台.在使用这个模型之前应该确保该系统安装了Winsock2.重叠模型的基本设计原理是使用一个重叠的数据结构,一次投递一个或多个Winsock ...

  8. 移植开源QT软件-SameGame

    前言: QML是一种描述性的脚本语言,文件格式以.qml结尾.语法格式非常像CSS(参考后文具体例子),但又支持javascript形式的编程控制.我个人认为它结合了QtDesigner UI和QtS ...

  9. Find Bugs

    为什么没有早点知道有这么好用的插件呢?

  10. PhotoZoom Pro 7怎么进行参数设置

    每个用户在使用PhotoZoom时,在针对不同的图片,我们处理的方式也不同.所以在参数设置会因图片不同而不同.那么在PhotoZoom中参数究竟如何设置呢? 首先,我们先打开[参数设置],点击后会弹出 ...