链接:http://acm.hdu.edu.cn/showproblem.php?pid=4686

题意:

其中a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY

最后的结果mod 1,000,000,007

n<=10^18.

分析:ai*bi=(ai-1 *ax+ay)*(bi-1 *bx+by)

=(ai-1 * bi-1 *ax*bx)+(ai-1 *ax*by)+(bi-1 *bx*ay)+(ay*by)

设p=ax*bx,  q=ax*by,  r=ay*bx,  s=ay*by

所以ai*bi=p(ai-1 * bi-1)+q(ai-1)+r(bi-1)+s

虽然可以用递推来求出每一项,但是n太大了,直接求绝对会超时的。

设f(n)=an*bn,  a(n)=an,  b(n)=bn

s(n)=sum(ai*bi),i=0,1,...n

则f(i)=p*f(i-1)+q*a(i-1)+r*b(i-1)+s

这是一个递推式,对于任何一个递推式,我们都可以用矩阵法来优化,加快速度求出第n项或前n项和。

我们可以构造一个5*5的矩阵A,使得

【f(n-1),a(n-1),b(n-1),1,s(n-2)】*A=【f(n),a(n),b(n),1,s(n-1)】

=【p*f(n-1)+q*a(n-1)+r*b(n-1)+s, a(n-1)*ax+ay, b(n-1)*bx+by, 1, s(n-2)+f(n-1)】

所以我们容易得出矩阵A: 【   axbx    0   0   0   1

axby   ax   0   0   0

aybx    0   bx  0   0

ayay   ay  by   1   0

0         0    0    0   1 】

由【f(1), a(1) ,b(1), 1, s(0)】*A = 【f(2), a(2), b(2), 1, s(1)】

以此类推得,【f(1), a(1) ,b(1), 1, s(0)】*A^(n-1) = 【f(n), a(n), b(n), 1, s(n-1)】

这样就可以快速的求出s(n-1)了,

其中f(1)=a1*b1, a(1)=a0*ax+ay,

b(1)=b0*bx+by, s(0)=a0*b0

接下来就是矩阵快速幂了。

注意:n==0时,直接输出0,不然会死循环TLE的,还有就是要用long long,也要记得mod

AC代码如下:

 #include<stdio.h>
#include<string.h>
//#define LL __int64
#define LL long long
#define M 1000000007
struct Matrix
{
LL a[][];
}origin,res,tmp,A,ans;
int n;
Matrix mul(Matrix x,Matrix y)
{
int i,j,k;
memset(tmp.a,,sizeof(tmp.a));
for(i=;i<=n;i++)
for(j=;j<=n;j++)
for(k=;k<=n;k++)
{
tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%M;
tmp.a[i][j]%=M;
}
return tmp;
}
void quickpow(LL k)
{
int i;
memset(res.a,,sizeof(res.a));
for(i=;i<=n;i++)
res.a[i][i]=;
while(k)
{
if(k&)
res=mul(res,A);
A=mul(A,A);
k>>=;
}
}
int main()
{
LL N,a0,ax,ay,b0,bx,by;
LL f1,a1,b1,s0;
// while(scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d",&N,&a0,&ax,&ay,&b0,&bx,&by)!=EOF)
while(scanf("%lld %lld %lld %lld %lld %lld %lld",&N,&a0,&ax,&ay,&b0,&bx,&by)!=EOF)
{
if(N==)
{
printf("0\n");
continue;
}
a1=(a0*ax+ay)%M;
b1=(b0*bx+by)%M;
f1=(a1*b1)%M;
s0=(a0*b0)%M;
n=;
memset(origin.a,,sizeof(origin.a));
origin.a[][]=f1;
origin.a[][]=a1;
origin.a[][]=b1;
origin.a[][]=;
origin.a[][]=s0;
memset(A.a,,sizeof(A.a));
A.a[][]=(ax*bx)%M;
A.a[][]=;
A.a[][]=(ax*by)%M;
A.a[][]=ax%M;
A.a[][]=(ay*bx)%M;
A.a[][]=bx%M;
A.a[][]=(ay*by)%M;
A.a[][]=ay%M;
A.a[][]=by%M;
A.a[][]=;
A.a[][]=; quickpow(N-);
ans=mul(origin,res);
// printf("%I64d\n",ans.a[1][5]);
printf("%lld\n",ans.a[][]);
}
return ;
}

hdu 4686 Arc of Dream(矩阵快速幂)的更多相关文章

  1. HDU 4686 Arc of Dream 矩阵快速幂,线性同余 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=4686 当看到n为小于64位整数的数字时,就应该有个感觉,acm范畴内这应该是道矩阵快速幂 Ai,Bi的递推式题目 ...

  2. hdu 4686 Arc of Dream_矩阵快速幂

    题意:略 构造出矩阵就行了 |   AX   0    AXBY   AXBY       0  |                                                   ...

  3. HDU4686 Arc of Dream 矩阵快速幂

    Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tota ...

  4. HDU4686——Arc of Dream矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4686 题目大意: 已知a0=A0, ai=Ax*ai-1+Ay; b0=B0, bi=Bx*bi-1 ...

  5. S - Arc of Dream 矩阵快速幂

    An Arc of Dream is a curve defined by following function: where a 0 = A0 a i = a i-1*AX+AY b 0 = B0  ...

  6. hdu----(4686)Arc of Dream(矩阵快速幂)

    Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tota ...

  7. HDOJ 4686 Arc of Dream 矩阵高速幂

    矩阵高速幂: 依据关系够建矩阵 , 高速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/ ...

  8. HDU 4686 Arc of Dream(矩阵)

    Arc of Dream [题目链接]Arc of Dream [题目类型]矩阵 &题解: 这题你做的复杂与否很大取决于你建的矩阵是什么样的,膜一发kuangbin大神的矩阵: 还有几个坑点: ...

  9. HDU4686 Arc of Dream —— 矩阵快速幂

    题目链接:https://vjudge.net/problem/HDU-4686 Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memo ...

随机推荐

  1. 3235: [Ahoi2013]好方的蛇

    3235: [Ahoi2013]好方的蛇 链接 分析: 可以求出以每个点为顶点的满足条件的矩形有多少个,单调栈求.设为sum. 然后对这个数组进行二维前缀和,可以求出每个矩阵内,以右下角.左下角为端点 ...

  2. JAVAWEB servlet验证登录时进行完全的非空判断防止空值登录

    如果不进行完全的非空判断,那么对 "" 这种类型的空值就会导致直接登录 所以需要用下面的字符串处理方法对其进行判断 这样就可以防止空值登录了 容易出现的混淆错误: 这里的空值登录容 ...

  3. js问题 window.location.hash和window.location.href有什么不同

    hash:设置或获取 href 属性中在井号“#”后面的分段. href:设置或获取整个 URL 为字符串. 通过下面的测试你会发现区别,将代码放到你的HTML中,然后用浏览器打开,测试步骤: 点击“ ...

  4. OpenGL(2)-窗口

    写在前面 通过本节,你可以毫不费力的--->创建一个窗口 OpenGL中窗口,即载体 导入头文件 #include <glad/glad.h> #include <GLFW/g ...

  5. [Lua] try catch实现

    参考了https://blog.csdn.net/waruqi/article/details/53649634这里的代码,但实际使用时还有些问题,修改后在此记录一下. -- 异常捕获 functio ...

  6. NIO - Buffer

    NIO —— Buffer源码分析 Buffer的类结构 底层的基础类是抽象类-Buffer,其中定义了四个变量:capacity(容量),limit(限制),position(位置),mark(标记 ...

  7. linux下实现压测-html报表生成-控制台参数优化【jmeter】

    jmeter - 单机压测 - 命令行模式-html报表生成-控制台参数优化 一/ 准备工作 1.压力机安装并配置好 jdk 2.调试好程序脚本 再上传到 linux下 3.进入jmeter  bin ...

  8. PHP核心技术——继承与多态

    继承: class person{ public $name='Tom'; public $gender; static $money=10000; public function __constru ...

  9. Axure 制作 轮播 左右按钮轮播图

    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ...

  10. Java创建对象的动作分析

    一.Java创建对象时将对象存放到内存的堆中. 创建对象时先执行类成员的初始化,然后才会调用构造函数初始化对象, package com.test.createsort; public class C ...