hdu2814

链接:点击打开链接

题意:求出F(a^b)^(F(a^b)^(n-1))%c(F为斐波那契数的值)

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
unsigned long long f[20005];                    //注意要使用无符号形
unsigned long long phi(unsigned long long n){   //欧拉函数值
    unsigned long long sum=n,i;
    for(i=2;i*i<=n;i++){
        if(n%i==0){
            sum-=sum/i;
            while(n%i==0)
            n/=i;
        }
    }
    if(n>1)
    sum-=sum/n;
    return sum;
}
unsigned long long quickmod(unsigned long long a,unsigned long long b,unsigned long long m){
    unsigned long long sum=1;                   //快速幂
    a=a%m;
    while(b){
        if(b&1)
        sum=sum*a%m;
        b>>=1;
        a=a*a%m;
    }
    return sum;
}
unsigned long long loop(unsigned long long m){
    unsigned long long i;                       //求斐波那契数的循环节
    f[0]=0;f[1]=1;f[2]=1;
    for(i=3;;i++){
        f[i]=(f[i-1]+f[i-2])%m;
        if(f[i]==f[1]&&f[i-1]==f[0])
        return i-1;
    }
}
int main(){                                     //这道题主要运用了两个性质:
    unsigned long long a,b,n,c,i,j,l,ph,cur,sum;//1.a^b≡(amodc)^bmod?(c)+?(c)(modc),b>=?(c) ?(c)为c的欧拉函数值
    int k,t;                                    //2.斐波那契数列有一个性质,它的n次方取模会出现一个循环节.假设循环节长度为len,则F(a^b)modc=F(a^bmodlen)modc
    cin>>t;
    for(k=1;k<=t;k++){
        cin>>a>>b>>n>>c;
        printf("Case %d: ",k);
        if(c==1){                               //c等于0时,模一定为0
            printf("0\n");
            continue;
        }                                       //根据以上性质本题变为求F(a^b)^(F(a^b)^(n-1))%c(F()为斐波那契)
        ph=phi(c);                              //先求出欧拉函数值
        l=loop(c);                              //求循环
        cur=quickmod(a,b,l);
        cur=f[cur];                             //求出F[a^b%len]
        if(ph==1){                              //欧拉函数为1时单独考虑
            cout<<quickmod(cur,n-1,c)<<endl;
            continue;
        }
        l=loop(ph);
        sum=quickmod(a,b,l);
        sum=f[sum];                             //求出关于欧拉函数值F[a^b%len]
        sum=quickmod(sum,n-1,ph)+ph;
        cur=quickmod(cur,sum,c);                //从而求出结果
        cout<<cur<<endl;
    }
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 21:29:19

hdu2814的相关文章