hdu 4565 So Easy! (共轭构造+矩阵快速幂)

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=4565

题目大意:

  给出a,b,n,m,求出的值,

解题思路:

  因为题目中出现了开根号,和向上取整后求余,所以用矩阵快速幂加速求解过程的时候,会产生误差,就很自然地想到了凑数,因为(a-1)^2<b<a^2,得出0<a-sqrt(b)<1,则无论n取多大,(a-sqrt(b))^n都是小于1的,(a-sqrt(b))^n 与 (a+sqrt(b))^n共轭,两者展开后会相互抵销,所以((a-sqrt(b))^n + (a+sqrt(b))^n)为整数,假设((a-sqrt(b))^n + (a+sqrt(b))^n)用sn表示,则sn*(a+sqrt(b))+(a-sqrt(b)) = Sn+1 - (a^2-b)*Sn-1,进一步得出 Sn+1 = 2*a*Sn - (a*a - b) * Sn-1

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <cmath>
 7 #include <queue>
 8 using namespace std;
 9 #define LL __int64
10 LL a, b, n, m;
11 struct mat
12 {
13     LL p[2][2];
14 };
15
16 mat mul (mat x, mat y);
17 mat pow (mat x, mat y, LL z);
18
19 int main ()
20 {
21     mat x, y;
22     while (scanf ("%I64d %I64d %I64d %I64d", &a, &b, &n, &m) != EOF)
23     {
24         memset (x.p, 0, sizeof(x.p));
25         memset (y.p, 0, sizeof(y.p));
26         x.p[0][0] = (2*(a*a+b)%m+m)%m;//要用long long,int相乘的时候会溢出
27         x.p[0][1] = (2*a) % m;
28         y.p[0][0] = (2*a) % m;
29         y.p[0][1] = 1;
30         y.p[1][0] = ((b-a*a)%m+m)%m;
31         //y.p[1][0] = ((b-a*a)+m)%m;//这样取余是错误的,因为还有可能是负数,害wa了好几次
32         x = pow (x, y, n-1);
33         printf ("%I64d\n", x.p[0][1]);
34     }
35     return 0;
36 }
37
38 mat mul (mat x, mat y)
39 {
40     int i, j, k;
41     mat z;
42     memset (z.p, 0, sizeof(z.p));
43     for (i=0; i<2; i++)
44         for (j=0; j<2; j++)
45         {
46             for (k=0; k<2; k++)
47                  z.p[i][j] += x.p[i][k] * y.p[k][j];
48             z.p[i][j] = (z.p[i][j] + m )% m;
49         }
50     return z;
51 }
52 mat pow (mat x, mat y, LL z)
53 {
54     while (z)
55     {
56         if (z % 2)
57             x = mul(x,y);
58         y = mul (y, y);
59         z /= 2;
60     }
61     return x;
62 }
时间: 2024-10-19 08:00:12

hdu 4565 So Easy! (共轭构造+矩阵快速幂)的相关文章

HDU4565-So Easy!(共轭运用+矩阵快速幂)

题目链接 题意: 求解  思路: 记(a+b√)n为An,配项 Cn=An+Bn=(a+b√)n+(a?b√)n 两项恰好共轭,所以Cn是整数.又根据限制条件 (a?1)2<b<a2?0<a?b√<1?0<(a?b√)n<1?Bn<1 也就是说Cn=?An? Sn=(Cn)%m 求Cn的方法是递推. 对Cn乘以(a+b√)+(a?b√) 于是 Cn+1=2aCn?(a2?b)Cn?1 把这个递推式写成矩阵形式 [Cn+1Cn]=[2a1?(a2?b)0][CnCn

HDU 2256 Problem of Precision (矩阵快速幂)

HDU 2256 Problem of Precision (矩阵快速幂) ACM 题目地址:HDU 2256 Problem of Precision 题意: 给出一个式子,求值. 分析: 推起来最后那步会比较难想. 具体过程见: 表示共轭只听说过复数的和图的... 这构题痕迹好明显... 跟基友开玩笑说:如果遇到这种题,推到Xn+Yn*sqrt(6)这步时,打表最多只能打到10就爆int了,这是输出正解和Xn,说不定眼神好能发现ans = Xn * 2 - 1呢.= =... 代码: /*

HDU 5171 GTY&#39;s birthday gift 矩阵快速幂

点击打开链接 GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 225    Accepted Submission(s): 78 Problem Description FFZ's birthday is coming. GTY wants to give a gift to ZZF. He as

HDU 4965 Fast Matrix Calculation(矩阵快速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次,可以变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个只有6x6,就可以用矩阵快速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N]

hdu 4965 Fast Matrix Calculation(矩阵快速幂)2014多校训练第9场

Fast Matrix Calculation                                                                   Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description One day, Alice and Bob felt bored again, Bob knows Ali

HDU 2256 Problem of Precision(矩阵快速幂)+ HDU 4565

HDU 2256 题意: 计算?(2√+3√)2n?mod1024 思路: ∵f(n)=(2√+3√)2n=(5+26√)n=An+Bn?6√ ∴f(n?1)=An?1+Bn?1?6√ 又∵f(n)=(5+26√)?f(n?1) ∴f(n)=(5?An?1+12?Bn?1)+(2?An?1+5?Bn?1)?6√ 所以递推矩阵就是: (52125)?(An?1Bn?1)=(AnBn) A1=5,B1=2. 然后套矩阵快速幂模板即可求出An,Bn. 又∵(5+26√)n=An+Bn?6√ ∴(5?2

hdu 1757 A Simple Math Problem 矩阵快速幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);And ai(0<=i<=9) can only be 0 or 1 .Now, I w

HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)

M斐波那契数列 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input 输入包含多组测试数据: 每组数据占一行,包含3个整数a,

HDU 2256 Problem of Precision(矩阵快速幂)

题目:就是求(sqrt(2)+sqrt(3))^(2*n)向下取整然后在MOD1024 思路:这个题挺有意思,但是这个题我觉得只能这样了,因为这个题可以做是因为这个题目限制的很死,我们把(sqrt(2)+sqrt(3))转化为(5+2*sqrt(6))^n 设Sn=An+bn,An=(5+2*sqrt(6))^n,Bn=(5-2*sqrt(6))^n,可以发现Bn是小于1的,那我们最后的答案就是Sn-1取模 然后我们构造Sn*((5+2*sqrt(6))+(5-2*sqrt(6))),继续化简就