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

news/2025/5/25 8:16:34

链接: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代码如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 //#define LL __int64
 4 #define LL long long
 5 #define M 1000000007
 6 struct Matrix
 7 {
 8     LL a[6][6];
 9 }origin,res,tmp,A,ans;
10 int n;
11 Matrix mul(Matrix x,Matrix y)
12 {
13     int i,j,k;
14     memset(tmp.a,0,sizeof(tmp.a));
15     for(i=1;i<=n;i++)
16         for(j=1;j<=n;j++)
17             for(k=1;k<=n;k++)
18             {
19                 tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%M;
20                 tmp.a[i][j]%=M;
21             }
22     return tmp;
23 }
24 void quickpow(LL k)
25 {
26     int i;
27     memset(res.a,0,sizeof(res.a));
28     for(i=1;i<=n;i++)
29         res.a[i][i]=1;
30     while(k)
31     {
32         if(k&1)
33             res=mul(res,A);
34         A=mul(A,A);
35         k>>=1;
36     }
37 }
38 int main()
39 {
40     LL N,a0,ax,ay,b0,bx,by;
41     LL f1,a1,b1,s0;
42 //    while(scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d",&N,&a0,&ax,&ay,&b0,&bx,&by)!=EOF)
43     while(scanf("%lld %lld %lld %lld %lld %lld %lld",&N,&a0,&ax,&ay,&b0,&bx,&by)!=EOF)
44     {
45         if(N==0)
46         {
47             printf("0\n");
48             continue;
49         }
50         a1=(a0*ax+ay)%M;
51         b1=(b0*bx+by)%M;
52         f1=(a1*b1)%M;
53         s0=(a0*b0)%M;
54         n=5;
55         memset(origin.a,0,sizeof(origin.a));
56         origin.a[1][1]=f1;
57         origin.a[1][2]=a1;
58         origin.a[1][3]=b1;
59         origin.a[1][4]=1;
60         origin.a[1][5]=s0;
61         memset(A.a,0,sizeof(A.a));
62         A.a[1][1]=(ax*bx)%M;
63         A.a[1][5]=1;
64         A.a[2][1]=(ax*by)%M;
65         A.a[2][2]=ax%M;
66         A.a[3][1]=(ay*bx)%M;
67         A.a[3][3]=bx%M;
68         A.a[4][1]=(ay*by)%M;
69         A.a[4][2]=ay%M;
70         A.a[4][3]=by%M;
71         A.a[4][4]=1;
72         A.a[5][5]=1;
73 
74         quickpow(N-1);
75         ans=mul(origin,res);
76     //    printf("%I64d\n",ans.a[1][5]);
77         printf("%lld\n",ans.a[1][5]);
78     }
79     return 0;
80 }
View Code

 

 

转载于:https://www.cnblogs.com/frog112111/p/3273660.html

文章来源:https://blog.csdn.net/weixin_30466421/article/details/97096760
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://dhexx.cn/news/show-18265.html

相关文章

纠结的CLI C++与Native C++的交互

最近在写点东西&#xff0c;涉及到了CLR C与Native C的互相调用的问题&#xff0c;结果...........纠结啊。 交互原型 交互原型是这样的&#xff1a; void* avio_alloc_context(unsigned char *buffer,int buffer_size,int write_flag,void *opaque,int (*read_packet)(void *o…

kafka概述,架构说明,相关的名词解释

消息队列两种模式&#xff1a;点对点与发布订阅 生产者发送一条消息到queue&#xff0c;只有一个消费者能收到。 发布者发送到topic的消息&#xff0c;只要订阅了该topic的订阅者都会收到消息。kafka架构图 Kafka 是一个分布式(发布订阅的)消息队列。Kafka 对消息保存时根据 …

JAVA基础知识

JAVA基础知识一、什么是对象二、JVM性能调优1、栈2、程序计数器3、堆4、方法区&#xff08;1.8后称元空间&#xff09;5、本地方法栈6、STW7、总结三、Jdk和Jre和Jvm四、与equals五、final六、String、StringBuffer、StringBuilder七、重载和重写八、抽象类和接口的区别九、lis…

栈Stack和段寄存器SS,SP(学习汇编)

1. 栈有2个基本操作&#xff1a;入栈、出栈 2. 栈顶的元素总是最后入栈&#xff0c;最先出栈&#xff1b;后进先出。 3. 8086CPU提供入栈和出栈的指令&#xff0c;最基本的两个是 PUSH(入栈) 和 POP(出栈) push ax 表示将AX寄存器的内容送入栈中&#xff0c; pop ax 表示从栈…

【转载】Linux下动态共享库加载时的搜索路径详解

转载自&#xff1a;http://www.eefocus.com/article/09-04/71617s.html 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading shared libraries”这样的错误&#xff0c;这是典型的因为需要的动态库不在动态链接器ld.so的搜索路径设置当中导致的。 …

Linux下打包和解压zip文件

Linux下打包zip文件一、压缩二、解压一、压缩 安装zip命令 yum install zipzip [参数] [打包后的文件名] [打包的目录路径]选项描述-a将文件转成ASCII模式-F尝试修复损坏的压缩文件-h显示帮助界面-m将文件压缩之后&#xff0c;删除源文件-n特定字符串 不压缩具有特定字尾字符…

kafka四大核心api

使用 Producer API 发布消息到kafka集群中一个或多个topic。 (重点掌握) 使用 Consumer API 来订阅一个或多个topic&#xff0c;并处理产生的消息。 (重点掌握) 使用 Streams API 充当一个流处理器&#xff0c;从1个或多个topic消费输入流&#xff0c;并生产输出流到1个或多个…

java List的用法

List的用法List包括List接口以及List接口的所有实现类。因为List接口实现了Collection接口&#xff0c;所以List接口拥有Collection接口提供的所有常用方法&#xff0c;又因为List是列表类型&#xff0c;所以List接口还提供了一些适合于自身的常用方法&#xff0c;如表1所示。表…

抽象数据类型的表示与实现

各种字符的定义代码如下&#xff1a; // liyuechao // 2014.8.7 // c1.h//c1.h文件名字 #include<string.h> #include<ctype.h> #include<malloc.h> // malloc()等 #include<limits.h> // INT_MAX等 #include<stdio.h> // EOF(^Z或F6),…

kafka工作流程分析-生产过程

Kafka 生产过程分析 写入方式producer 采用推&#xff08;push&#xff09;模式将消息发布到 broker&#xff0c;每条消息都被追加&#xff08;append&#xff09;到分区&#xff08;patition&#xff09;中&#xff0c;属于顺序写磁盘&#xff08;顺序写磁盘效率比随机写内存要…