HDU4686---Arc of Dream(矩阵快速幂,大数据的坑题)
来源:互联网 发布:java毕业设计免费下载 编辑:程序博客网 时间:2024/05/21 10:50
【题目来源】:https://vjudge.net/problem/HDU-4686
【题意】
题意如题面所述。AD(i)=AD(i-1)+ai*bi。
【思路】
很明显,矩阵快速幂,但是这道题相当坑。
第一:若是没有n==0的情况会给出超时的结果。(我还一直在想log
的复杂度怎么会超时)
第二:乘法中间的过程必须各种取余,否则会爆longlong。
好了,步入正题:
很多博客直接给出了现成的矩阵式子或者图形,新手估计看的一脸懵逼,那么我就给出一下我的推导过程吧。
首先呢,找出总的关系式:
AD(i)=AD(i-1)+a(i)*b(i)。
然后把右边所有i换成i-1,因为矩阵是这么个意思:前一项乘以系数矩阵得到下一项,也就是第i-1项乘以系数矩阵得到第i项,所以两边的元素要分清。
AD(i)=AD(i-1)+(a(i-1)*ax+ay)(b(i-1)*bx+by)
化简得:
AD(i)=AD(i-1)+ax*bx*a(i-1)*b(i-1)+ax*by*a(i-1)+ay*bx*b(i-1)+ay*by;
这个时候呢,递推式就出来了,那么接下来写出系数矩阵:
(的第一行,,嘿嘿)由等号右边的式子可得系数:
1 ax*bx ax*by ay*bx ayby
上面呢系数矩阵的第一行,那么该怎么推以下几行呢?(继续看)
刚才已经说过,是第i-1项乘以系数矩阵得到第i项,那么每个式子都会的到下一项:(以下是初始矩阵(也就是右边除了系数之外的))
初始矩阵(坐标)当前项————>下一项(矩阵坐标)
AD(i-1)(1,1)—————–>AD(i)(1,1)
a[i-1]*b[i-1](2,1)————>a[i]*b[i](2,1)
a[i-1](3,1)——————->a[i](3,1)
b[i-1](4,1)——————->b[i](4,1)
1(5,1)———————–>1(5,1)
由于矩阵乘法可知:
AD(i)的坐标是(1,1),那么就等于系数矩阵的第一行乘以初始矩阵的第一列;
a[i]*b[i]的坐标是(2,1),那么就等于系数矩阵的第二行乘以初始矩阵的第二列;(以此来推出系数矩阵的第二行)
。。。
。。。
。。。
( 这也是一般系数矩阵的推理方法)
然后推出的系数矩阵是这样的:
然后这道题就可以做了。。。
【代码】
#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const LL mod=1e9+7;LL a0,ax,ay;LL b0,bx,by;struct mat{ LL a[6][6];};mat operator*(mat &s,mat &t){ mat r; memset(r.a,0,sizeof(r.a)); for(int i=1; i<=5; i++) { for(int j=1; j<=5; j++) { for(int k=1; k<=5; k++) { r.a[i][j]+=(s.a[i][k]*t.a[k][j])%mod; r.a[i][j]%=mod; } } } return r;}LL pow_mat(mat base,LL k){ mat ans; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) ans.a[i][j]=(i==j); while(k) { if(k&1) { ans=ans*base; } base=base*base; k>>=1; } return (ans.a[1][1]*a0%mod*b0%mod+ans.a[1][2]*a0%mod*b0%mod+ans.a[1][3]*a0%mod+ans.a[1][4]*b0%mod+ans.a[1][5]%mod)%mod;//相当于初始矩阵与系数矩阵的乘法}int main(){ LL n; while(~scanf("%lld",&n)) { scanf("%lld%lld%lld",&a0,&ax,&ay); scanf("%lld%lld%lld",&b0,&bx,&by); mat base; memset(base.a,0,sizeof(base.a)); base.a[1][1]=1; base.a[1][2]=ax*bx%mod; base.a[1][3]=ax*by%mod; base.a[1][4]=ay*bx%mod; base.a[1][5]=ay*by%mod; base.a[2][2]=ax*bx%mod; base.a[2][3]=ax*by%mod; base.a[2][4]=ay*bx%mod; base.a[2][5]=ay*by%mod; base.a[3][3]=ax; base.a[3][5]=ay; base.a[4][4]=bx; base.a[4][5]=by; base.a[5][5]=1; if(n==0) { printf("0\n"); continue; } printf("%lld\n",pow_mat(base,n-1)); }}
- HDU4686---Arc of Dream(矩阵快速幂,大数据的坑题)
- HDU4686 Arc of Dream 矩阵快速幂
- (矩阵快速幂)hdu4686 Arc of Dream
- hdu4686 Arc of Dream ——构造矩阵+快速幂
- hdu4686---Arc of Dream(矩阵)
- HDU4686 Arc of dream
- hdu4686 Arc of Dream
- HDU4686 Arc of Dream
- Arc of Dream(矩阵快速幂)
- hdu 4686 Arc of Dream(构造矩阵快速幂)
- hdu 4686 Arc of Dream(矩阵快速幂)
- HDU 4684 - Arc of Dream(矩阵快速幂)
- HDU 4686 Arc of Dream(矩阵快速幂)
- HDU 4686 Arc of Dream(矩阵快速幂)
- HDU 4686 Arc of Dream(矩阵快速幂)
- hdu 4686 Arc of Dream(矩阵快速幂)
- HDU 4686 Arc of Dream(矩阵快速幂)
- HDU 4686 Arc of Dream(矩阵快速幂)
- 二叉树递归和非递归访问的实现
- Horizon 二次开发
- MFC调用dll文件
- Java习题札记
- Linux shell 脚本
- HDU4686---Arc of Dream(矩阵快速幂,大数据的坑题)
- 学习笔记2017.07.07-day5,am-HTML表单-HTML框架
- 防止Windows自动锁屏的VBA脚本
- 欢迎使用CSDN-markdown编辑器
- mysql 注意事项
- 日期函数
- Js作用域链及变量作用域
- 开源一款资源分享与下载工具 —— 电驴(eMule)
- Apache与Tomcat 区别联系