• 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
    ", 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    前端 fetch 通信
    编写高质量的JavaScript代码(一)
    Redis学习笔记1-Redis的介绍和认识
    gitignore不起作用解决的方法
    【我的面经】说说简历的细节——软件开发岗位
    菜鸟的mongoDB学习---(七)MongoDB 备份(mongodump)与恢复(mongorerstore)
    HDU 4927 Series 1
    树状数组求第K小值 (spoj227 Ordering the Soldiers &amp;&amp; hdu2852 KiKi&#39;s K-Number)
    git和SVN的差别
    KVM-Introduce
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4473491.html
Copyright © 2020-2023  润新知