zoukankan      html  css  js  c++  java
  • HDU5667—Sequence(对数转化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5667

    题目意思:f1=1,i=1

         f2=2 ,i=2

         fi=a^b*f[i-1]^c*f[i-2] i>2

    思路:发现a^b,和f[i-1]^c之类的东西,我们很明显吧这个幂变成乘,很自然的想到对数。问题是对什么取对数,最后发现对a取对数是合适的。

    loga(fi)=loga(a^b*f[i-1]^c*f[i-2])=loga(a^b)+loga(f[i-1]^c)+loga(f[i-2]),我们设k[i]=loga(fi),所以k[i]=b+c*k[i-1]+k[i-2]。我们可以通过矩阵快速幂算出k[n],然后a^k[n]=f[n],可以直接用快速幂算出。

    这里注意一下,由于k[n]非常大,所以为了使得a^k[n]%p==(a^(k[n]%y))%p,根据费马小定理如何gcd(a,p)=1,那么 a^(p-1)≡1(mod p),所以a^(p-1)%p=a^0%p,所以循环节为p-1,所以a^(k[n]%(p-1))%p。

    这里还有注意一下如果a%p==0,a^(k[n]%(p-1))%p当k[n]=p-1的时候,a^(k[n]%(p-1))%p=1,但是实际上a^(k[n]%(p-1))%p=0,会造成错误,所以需要特判a%p==0的情况,不过这个题好像后台题目有点水,不必判断也能过貌似,所以代码里面没有体现

    代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 #define LL long long
     8 LL p,aa,bb,cc,n,mod; //mod为p-1
     9 struct matrix
    10 {
    11     LL mat[3][3];
    12 };
    13 matrix pow1(matrix a,matrix b) // N^3的矩阵相乘
    14 {
    15     matrix c;
    16     memset(c.mat,0,sizeof(c.mat));
    17     for(int i=0;i<3;i++){
    18         for(int j=0;j<3;j++){
    19             for(int k=0;k<3;k++){
    20                 c.mat[i][j] += (a.mat[i][k]*b.mat[k][j]);
    21                 c.mat[i][j] %= mod;
    22             }
    23         }
    24     }
    25     return c;
    26 }
    27 matrix cheng(matrix a,LL y) //矩阵快速幂
    28 {
    29     matrix b;
    30     memset(b.mat,0,sizeof(b.mat));
    31     for(int i=0;i<3;i++) b.mat[i][i] = 1;
    32     while(y){
    33         if(y&1){
    34             b = pow1(a,b);
    35             y-=1;
    36         }else {
    37             a = pow1(a,a);
    38             y/=2;
    39         }
    40     }
    41     return b;
    42 }
    43 LL quick_pow(LL a,LL tmp) //对a进行快速幂
    44 {
    45     LL b = 1ll;
    46     while(tmp)
    47     {
    48         if(tmp&1) b=(a*b)%p;
    49         a=(a*a)%p;
    50         tmp>>=1;
    51     }
    52     return b;
    53 }
    54 int main()
    55 {
    56     int t;
    57     scanf("%d",&t);
    58     while(t--){
    59         scanf("%lld%lld%lld%lld%lld",&n,&aa,&bb,&cc,&p);
    60         matrix ma;
    61         mod = p-1;
    62         memset(ma.mat,0,sizeof(ma.mat));//初始化递归矩阵
    63         ma.mat[0][0] = cc; ma.mat[0][1] = 1; ma.mat[0][2] = bb;
    64         ma.mat[1][0] = 1; ma.mat[2][2] = 1;
    65 
    66 
    67         ma = cheng(ma,n-2); //算指数和直接幂有点不同
    68         LL tmp = ma.mat[0][0]*bb + ma.mat[0][2]; //取出指数
    69         LL ans = quick_pow(aa,tmp);
    70         printf("%lld
    ",ans);
    71 
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    数据类型装换
    变量及数据类型
    27 网络通信协议 udp tcp
    26 socket简单操作
    26 socket简单操作
    14 内置函数 递归 二分法查找
    15 装饰器 开闭原则 代参装饰器 多个装饰器同一函数应用
    12 生成器和生成器函数以及各种推导式
    13 内置函数 匿名函数 eval,exec,compile
    10 函数进阶 动态传参 作用域和名称空间 函数的嵌套 全局变量
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7354540.html
Copyright © 2011-2022 走看看