博客
关于我
2020牛客寒假集训第一场J题——矩阵快速幂
阅读量:656 次
发布时间:2019-03-15

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

 题目链接:

题目描述:

给你5个数 :n,x,y,a,b(1<=n,x,y,z,b<=1e12)

f(1)=x,f(2)=y,f(i)=f(i-1)*f(i-2)*a^b(i>3)

 让你求f(n)%1e9+7的值

题解:

f(1)=x;

f(2)=y;
f(3)=x*y*a^b;
f(4)=x*y*a^b*y*a^b=x*y^2*a^2b
f(5)=x*y^2*a^2b*x*y*a^b*a^b=x^2*y^3*a^4b
f(6)=x^2*y^3*a^4b*x*y^2*a^2b=x^3*y^5*a^6b
设c为常数
      c      x      y
1   0      1      0
2   0      0      1
3   1      1      1
4   2      1      2
5   4      2      3
6   6      3      5
c:
i<3:fb2(1)=fb2(2)=0;
i>=3:fb2(i)=fb2(i-1)+fb2(i-1)+1;
//注意不能化成fb2(i)=fb2(i-1)*fb2(i-2)*a^b;
//因为这样不能用常量矩阵来维护,因为矩阵乘法的每一项的结果是相加的。
ans1=a^(b*fb2(i)),相当于只维护幂次和
1 1 1     fb2(i-1)       fb2(i)
1 0 0 *  fb2(i-2)  =   fb2(i-1)
0 0 1    1                 1
设t为3*3的矩阵{
{1,1,1},{1,0,0},{0,0,1}};
设ai为3*1的矩阵{fb2(i),fb2(i-1),1}
则a1={fb2(2),fb2(1),1}
ai=a(i-1)*t
a2=a1*t
a3=a2*t=a1*t^2
=>ai=a1*t^(i-1)
=>        
              fb2(2)        fb2(i)
t^(i-1) *  fb2(1)  =    fb2(i-1)
             1                1
如果要求fb2(n) 
利用矩阵快速幂求出t^(n-1)
fb2(n)=t^(n-1)的第一行*a1的第一列(即矩阵{0,0,1})
则c对答案的贡献为 ans1=a^(b*fb2(n))(可以用快速幂求)

x:

i<3:fb1(1)=1, fb1(2)=0;
i>=3:fb1(i)=fb1(i-1)+fb1(i-2);
1 1     fb1(i-1)     fb1(i)
1 0  *  fb1(i-2)  =  fb1(i-1)
设t为2*2的矩阵{
{1,1},{1,0}}
设ai为2*1的矩阵{fb1(i),fb1(i-1)}
则a1为2*1的矩阵{fb1(2),fb1(1)}
ai=a(i-1)*t; 
a2=a1*t
a3=a2*t=a1*t*t=a1*t^2
a4=a3*t=a1*t*t*t=a*t^3;
根据递推式可得
ai=a1*t^(i-1);
即   
t^(i-1)      fb1(2)      fb1(i)
           *   fb1(1)  =  fb1(i-1).
故fb1(n)=t^(n-1)的第一行*a1(即矩阵{0,1}) 
因此对答案的贡献是 ans2=x^fb1(n);
y:
i<3:fb1(1)=0,fb1(2)=1;
i>=3:fb1(i)=fb1(i-1)+fb1(i-2);
推导过程和上面类似,只不过初始值变了
可以自己再推一遍。
最后答案就是ans1*ans2%mod*ans3%mod
trick:
1.因为x和y的递推都是斐波那契数列,只不过初始值变了,而且x比y多了一位,所以我们可以放在一起考虑。
2.a^b对上面的指数取模时不能直接取,需要用到费马小定理
定理内容:如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)
3.根据上面的定理所以我们需要特判a是p的倍数的情况以及x,y是p的倍数的情况。

代码实现:

#pragma GCC optimize(2)#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PI atan(1.0)*4#define E 2.718281828#define rp(i,s,t) for (register int i = (s); i <= (t); i++)#define RP(i,t,s) for (register int i = (t); i >= (s); i--)#define ll long long#define ull unsigned long long#define mst(a,b) memset(a,b,sizeof(a))#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define pii pair
#define mp make_pair#define pb push_backusing namespace std;inline int read(){ int a=0,b=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') b=-1; c=getchar(); } while(c>='0'&&c<='9') { a=(a<<3)+(a<<1)+c-'0'; c=getchar(); } return a*b;}ll n,x,y,a,b;const int INF = 0x3f3f3f3f;const ll mod = 1e9+7;struct matrix{ ll a[3][3];};matrix mul(matrix a,matrix b, ll m){ matrix res; rp(i,0,2) rp(j,0,2){ res.a[i][j]=0; rp(k,0,2){ res.a[i][j]=(res.a[i][j]+a.a[i][k]*b.a[k][j]%m)%m; } } return res;}matrix matrix_pow(matrix a,ll b,ll m){ matrix res; rp(i,0,2) rp(j,0,2) res.a[i][j]=0; res.a[1][1]=res.a[0][0]=res.a[2][2]=1; while(b){ if(b&1) res=mul(res,a,m); b>>=1; a=mul(a,a,m); } return res;}ll fb1(int flag,ll n,ll m){ matrix tmp; rp(i,0,2) rp(j,0,2) tmp.a[i][j]=0; tmp.a[0][0]=tmp.a[0][1]=tmp.a[1][0]=1; tmp=matrix_pow(tmp,n-1,m); if(flag==1) return tmp.a[0][1]%m; else return tmp.a[0][0]%m;}ll fb2(ll n,ll m){ matrix tmp; rp(i,0,2) rp(j,0,2) tmp.a[i][j]=0; tmp.a[0][0]=tmp.a[0][1]=tmp.a[0][2]=tmp.a[1][0]=tmp.a[2][2]=1; tmp=matrix_pow(tmp,n-1,m); return tmp.a[0][2]%m;}ll quick_pow(ll a,ll b,ll m){ ll res=1; while(b){ if(b&1) res=(res*a)%m; a=(a*a)%m; b>>=1; } return res%m;}int main(){ scanf("%lld%lld%lld%lld%lld",&n,&x,&y,&a,&b); if(n==1) cout<
<

 

转载地址:http://nufmz.baihongyu.com/

你可能感兴趣的文章
Mysql5.7版本单机版my.cnf配置文件
查看>>
mysql5.7的安装和Navicat的安装
查看>>
mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
查看>>
Mysql8 数据库安装及主从配置 | Spring Cloud 2
查看>>
mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
查看>>
MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
查看>>
MYSQL8.0以上忘记root密码
查看>>
Mysql8.0以上重置初始密码的方法
查看>>
mysql8.0新特性-自增变量的持久化
查看>>
Mysql8.0注意url变更写法
查看>>
Mysql8.0的特性
查看>>
MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
查看>>
MySQL8修改密码的方法
查看>>
Mysql8在Centos上安装后忘记root密码如何重新设置
查看>>
Mysql8在Windows上离线安装时忘记root密码
查看>>
MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
查看>>
mysql8的安装与卸载
查看>>
MySQL8,体验不一样的安装方式!
查看>>
MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
查看>>
Mysql: 对换(替换)两条记录的同一个字段值
查看>>