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
  • 相关阅读:
    2019-3-24
    模板
    试试Markdown编辑器
    Codeforces Round #529 (Div. 3) D. Circular Dance
    Codeforces Round #529 (Div. 3) C. Powers Of Two(数学????)
    poj 2566"Bound Found"(尺取法)
    poj 3273"Monthly Expense"(二分搜索+最小化最大值)
    二分搜索
    Codeforces Round #518 (Div. 2) B LCM
    2018.12.21 浪在ACM 集训队第十次测试赛
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7354540.html
Copyright © 2011-2022 走看看