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


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

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

  我们发现这个递推的过程是线性的,所以可以用矩阵乘法来表示,$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)

 /**************************************************************
Problem: 3240
User: Tunix
Language: C++
Result: Accepted
Time:7980 ms
Memory:3232 kb
****************************************************************/ //BZOJ 3240
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e6+,INF=~0u>>,P=1e9+;
typedef long long LL;
/******************tamplate*********************/ struct Matrix{
int v[][];
Matrix(int x=){F(i,,)F(j,,)if(i==j)v[i][j]=x;else v[i][j]=;}
int* operator [] (int x){return v[x];}
}s1,s2,v;
inline Matrix operator * (Matrix a,Matrix b){
Matrix c;
if (a[][]== && a[][]== && b[][]== && b[][]==){
c[][]=(LL)a[][]*b[][]%P;
c[][]=;
c[][]=((LL)a[][]*b[][]+(LL)a[][])%P;
c[][]=;
return c;
}
F(k,,) F(i,,) F(j,,)
c[i][j]=((LL)c[i][j]+(LL)a[i][k]*b[k][j]%P)%P;
return c;
}
inline Matrix Pow(Matrix a,int b){
Matrix c();
F(i,,b) c=c*a;
return c;
}
inline Matrix Power(Matrix a,char* s){
Matrix r(); int l=strlen(s);
D(i,l-,){
if (s[i]-'') r=r*Pow(a,s[i]-'');
a=Pow(a,);
}
return r;
}
char n[N],m[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("3240.in","r",stdin);
freopen("3240.out","w",stdout);
#endif
scanf("%s",n); scanf("%s",m);
int l1=strlen(n)-;
while(n[l1]=='') n[l1--]='';
n[l1]--;
l1=strlen(m)-;
while(m[l1]=='') m[l1--]='';
m[l1]--;
// printf("%s %s\n",n,m);
int a,b,c,d;
a=getint(); b=getint(); c=getint(); d=getint();
v[][]=v[][]=; v[][]=v[][]=;
s1[][]=a; s1[][]=; s1[][]=b; s1[][]=;
s2[][]=c; s2[][]=; s2[][]=d; s2[][]=;
Matrix s3=Power(s1,m);
v=v*(Power(s3*s2,n)*s3);
printf("%d\n",v[][]);
return ;
}

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]

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

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

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

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

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

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

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

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

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

  5. (十进制高速幂+矩阵优化)BZOJ 3240 3240: [Noi2013]矩阵游戏

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=3240 3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  M ...

  6. 【BZOJ】3240: [Noi2013]矩阵游戏

    题意 给出\(n, m(1 \le n, m \le 10^{1000000})\),求\(f(n, m) \ \mod \ 10^9+7\) $$\begin{cases}f(1, 1) = 1 \ ...

  7. 3240: [Noi2013]矩阵游戏

    Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的 ...

  8. P1397 [NOI2013]矩阵游戏(递推)

    P1397 [NOI2013]矩阵游戏 一波化式子,$f[1][m]=a^{m-1}+b\sum_{i=0}^{m-2}a^i$,用快速幂+逆元求等比数列可以做到$logm$ 设$v=a^{m-1}, ...

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

    1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1891  Solved: 919[Submit][Statu ...

  10. BZOJ 1059 [ZJOI2007]矩阵游戏

    1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2707  Solved: 1322[Submit][Stat ...

随机推荐

  1. SQL Server 跨服务器快速数据转移

    最近遇到一个问题,要将 a 服务器上的 A 库,迁移到 b 服务器上的 B 库,两个库的数据结构是一样的,但是数据库版本是 a 比 b 高,通过 sqlserver  还原这条路是走不通了,那难道除了 ...

  2. Ionic Js七:手势事件

    1.on-hold 长按的时间是500毫秒. HTML 代码 <button on-hold="onHold()" class="button">长 ...

  3. thinkphp中如何是实现多表查询

    多表查询经常使用到,但如何在thinkphp中实现多表查询呢,其实有三种方法. 1 2 3 4 5 6 7 8 9 10 11 12 // 1.原生查询示例: $Model = new Model() ...

  4. 远程连接mysql root账号报错:2003-can't connect to MYSQL serve(转)

    远程连接mysql root账号报错:2003-can't connect to MYSQL serve 1.远程连接Linux系统,登录数据库:mysql -uroot -p(密码) 2.修改roo ...

  5. CSUOJ 1087 就多了两分钟

    Description Yucept21和他的室友Zyn因为宿舍没电去网吧上网,上了27分钟,Cs打电话来说来电了.所以Yucept21在第29分钟下机了,上网的费用是一块钱,然后Zyn墨迹了两分钟, ...

  6. [leetcode tree]100. Same Tree

    判断输入的两棵树是不是相同 判断当前root值,左子树和右子树是否相同 ####注意最后用的是 is 而不是 ==,因为最后判断p和q是不是None, 应该判断是不是同一个对象 class Solut ...

  7. 安卓 开机 动画 酷派大神F1开机动画 美化 自定义 修改

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 酷派大神F1开机动画.rar

  8. SpringBoot静态资源目录

    在web开发中,静态资源的访问是必不可少的,如:图片.js.css 等资源的访问. SpringBoot对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求. 在传统的web项目中静态资源 ...

  9. Splay-Tree理解

    简介 splay tree其实就是不停的旋转,没进行一个操作都要进行旋转:例如,当访问某一个结点的时候,会通过旋转其结点使得该结点变为树根,这样保证其的平均复杂度为O(nlogn); 其的操作包括: ...

  10. BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submi ...