博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【矩阵+十进制快速幂】[NOI2013]矩阵游戏
阅读量:4597 次
发布时间:2019-06-09

本文共 5339 字,大约阅读时间需要 17 分钟。

描述

婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的 nm 列的矩阵(你不用担心她如何存储)。她生成的这个矩阵满足一个神奇的性质:

若用 Fi,j 来表示矩阵中第 i 行第 j 列的元素,则 Fi,j 满足下面的递推式:

F1,1Fi,jFi,1===1aFi,j1+bcFi1,m+dj1i1

递推式中 a,b,c,d 都是给定的常数。 现在婷婷想知道 Fn,m 的值是多少,请你帮助她。由于最终结果可能很大,你只需要输出 Fn,m 除以 1000000007 的余数。

输入格式

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

输出格式

表示 Fn,m 除以 1000000007 的余数。

样例一

input

3 4 1 3 2 6

output

85

explanation

样例中的矩阵为:

126764297973282103585

样例二

见样例数据下载。

限制与约定

测试点编号 数据范围
1 1n,m101a,b,c,d1000
2 1n,m1001a,b,c,d1000
3 1n,m1031a,b,c,d109
4 1n,m1031a,b,c,d109
5 1n,m1091a=c1091b=d109
6 1n,m109a=c=11b,d109
7 1n,m,a,b,c,d109
8 1n,m,a,b,c,d109
9 1n,m,a,b,c,d109
10 1n,m,a,b,c,d109
11 1n,m101000a=c=11b,d109
12 1n,m1010001a=c1091b=d109
13 1n,m1010001a,b,c,d109
14 1n,m1010001a,b,c,d109
15 1n,m10200001a,b,c,d109
16 1n,m10200001a,b,c,d109
17 1n,m101000000a=c=11b,d109
18 1n,m1010000001a=c1091b=d109
19 1n,m1010000001a,b,c,d109
20 1n,m1010000001a,b,c,d109

时间限制:1s

空间限制:256MB

分析

可以很容易地推出矩阵

每一行

(Fi,j+11)=(Fi,j1)×(ab01)

行之间

(Fi+1,11)=(Fi,m1)×(cd01)
然后可以快速幂算出
Fi,1
Fi,m,然后算出和
Fi+1,1之间的矩阵。然后继续快速幂就好了。

由于指数是高精度数,所以使用十进制快速幂算比较方便。

代码

ps:高精度粘的版,很长。。。

#include
#include
#include
#define MOD 1000000007#define MAXLEN 1000000using namespace std;int a,b,c,d;char s[MAXLEN+10];void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}void Read_mod(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=(1ll*x*10+c-'0')%(MOD-1); ungetc(c,stdin); return; }}struct Matrix{ int a[2][2]; // f 1 inline Matrix(){ memset(a,0,sizeof a); } inline Matrix(int){ memset(a,0,sizeof a); for(int i=0;i<2;i++) a[i][i]=1; } inline Matrix operator*(const Matrix &b)const{ Matrix c; int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++) if(a[i][j]) for(k=0;k<2;k++) c.a[i][k]=(c.a[i][k]+1ll*a[i][j]*b.a[j][k])%MOD; return c; } inline Matrix &operator*=(const Matrix &b){ return *this=*this*b; }}A,B,C;struct hp{ int a[MAXLEN+10]; hp(){ memset(a,0,sizeof a); a[0]=1; } hp(int n){ memset(a,0,sizeof a); a[0]=0; while(n){ a[++a[0]]=n%10; n/=10; } if(!a[0]) a[0]=1; } hp(char *s){ memset(a,0,sizeof a); int len=strlen(s); for(int i=1;i<=len;i++) a[i]=s[len-i]-'0'; a[0]=len; } hp operator*(const hp &b)const{ hp c; int i,j,len=a[0]+b.a[0]; for(i=1;i<=a[0];i++) for(j=1;j<=b.a[0];j++) c.a[i+j-1]+=a[i]*b.a[j]; for(i=1;i
1&&!c.a[len]) len--; c.a[0]=len; return c; } hp operator/(int b)const{ hp c; int d=0,i,len=a[0]; for(i=a[0];i;i--){ d=d*10+a[i]; c.a[i]=d/b; d%=b; } while(len>1&&!c.a[len]) len--; c.a[0]=len; return c; } hp operator+(const hp &b)const{ hp c; int len=max(a[0],b.a[0]),i; for(i=1;i<=len;i++){ c.a[i]+=a[i]+b.a[i]; c.a[i+1]=c.a[i]/10; c.a[i]%=10; } len++; while(len>1&&!c.a[len]) len--; c.a[0]=len; return c; } hp operator-(const hp &b)const{ hp c; int i,len=a[0]; for(i=1;i<=len;i++){ c.a[i]+=a[i]-b.a[i]; if(c.a[i]<0) c.a[i]+=10,c.a[i+1]--; } while(len>1&&!c.a[len]) len--; c.a[0]=len; return c; } void operator*=(const hp &x){ *this=*this*x; } void operator/=(const int &x){ *this=*this/x; } void operator+=(const hp &x){ *this=*this+x; } void operator-=(const hp &x){ *this=*this-x; } void print(){ for(int i=a[0];i;i--) printf("%d",a[i]); } bool operator>(const hp&b)const{ if(a[0]>b.a[0]) return 1; if(a[0]
b.a[i]) return 1; else if(a[i]
b.a[0]) return 0; for(int i=a[0];i;i--) if(a[i]
b.a[i]) return 0; return 0; } bool operator<=(const hp&b)const{ return !(*this>b); } hp operator/(const hp&b)const{ hp l(0),r(*this),mid; while(l
T quick_pow(T a,int b){ T ret(1); while(b){ if(b&1) ret*=a; a*=a; b>>=1; } return ret;}void read(){ scanf("%s",s); n=s; scanf("%s",s); m=s; Read(a),Read(b),Read(c),Read(d);}template
T quick_pow10(T a,hp b){ int i; T ret(1),c[10]; c[0]=ret; for(i=1;i<10;i++) c[i]=c[i-1]*a; for(i=b.a[0];i;i--){ ret=quick_pow(ret,10); ret*=c[b.a[i]]; } return ret;}void solve(){ A.a[0][0]=a,A.a[1][0]=b,A.a[1][1]=1; B=quick_pow10(A,m-1); C.a[0][0]=c,C.a[1][0]=d,C.a[1][1]=1; A=B*C; A=quick_pow10(A,n-1); A*=B;}int main(){ read(); solve(); printf("%d\n",(A.a[0][0]+A.a[1][0])%MOD);}

转载于:https://www.cnblogs.com/outerform/p/5921819.html

你可能感兴趣的文章
利用/dev/urandom文件创建随机数
查看>>
js遍历获取表格内数据方法
查看>>
DVWA渗透测试环境搭建
查看>>
bzoj2219: 数论之神
查看>>
bzoj 3261: 最大异或和
查看>>
「折腾」用word发布博客
查看>>
C# 基本函数
查看>>
iOS审核秘籍】提审资源检查大法
查看>>
辗转相除法
查看>>
A2-02-29.DML-MySQL DELETE
查看>>
vue 路由跳转
查看>>
having 子句
查看>>
常用排序算法
查看>>
一个很好介绍js的例子
查看>>
POJ 3122 Pie
查看>>
RHEL存储扩容
查看>>
关于mongodb的安装运行
查看>>
Ubuntu总结常用命令记录
查看>>
逆袭大学
查看>>
数学题
查看>>