zoukankan      html  css  js  c++  java
  • 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    lombok 下的@Builder注解用法
    (springboot)自定义Starter
    各种 Spring-Boot-Starters系列 介绍
    MQ的使用场景
    SpringBoot中使用rabbitmq,activemq消息队列和rest服务的调用
    RPC原理详解
    Java性能优化的50个细节
    thinkphp3.2.2有预览的多图上传
    关于php中的exec命令
    关于thinkphp3.1无法加载模块解决办法
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4473491.html
Copyright © 2011-2022 走看看