hdu 4549 M斐波那契数列

http://acm.hdu.edu.cn/showproblem.php?pid=4549

思路:

观察a,b的幂符合斐波那契数列,因为n特别的大,所以构造矩阵求出a,b的第n的幂。 构造矩阵之后矩阵快速幂,因为在快速幂的时候矩阵相乘会超出__int64。所以需要用到一个定理

当gcd(a,mod)==1的时候  
a^x = a^( x mod Eular(mod) ) ( mod mod ) . 所以变成这样a^b%mod=a^(b%(mod-1))%mod; 

 1 #include <cstdio>

 2 #include<cstring>

 3 #include <algorithm>

 4 #define LL __int64

 5 using namespace std;

 6 const int mod=1e9+7;

 7 

 8 LL a,b,n;

 9 

10 struct node

11 {

12     LL a[4][4];

13 };

14 

15 node mul(node x,node y)

16 {

17     node c;

18     for(int i=0; i<2; i++)

19     {

20         for(int j=0; j<2; j++)

21         {

22             c.a[i][j]=0;

23             for(int k=0; k<2; k++)

24             {

25                 c.a[i][j]+=x.a[i][k]*y.a[k][j];

26                 c.a[i][j]%=(mod-1);

27             }

28         }

29     }

30     return c;

31 }

32 

33 node pow_m(node c,int n)

34 {

35     node temp;

36     memset(temp.a,0,sizeof(temp.a));

37     temp.a[0][0]=1; temp.a[1][1]=1;

38     node xx=c;

39     while(n)

40     {

41         if(n&1) temp=mul(temp,xx);

42         xx=mul(xx,xx);

43         n>>=1;

44     }

45     return temp;

46 }

47 

48 LL pow_M(LL a,LL n)

49 {

50     LL ans=1;

51     LL temp=a%mod;

52     while(n)

53     {

54         if(n&1)

55         {

56             ans*=temp;

57             ans%=mod;

58         }

59         temp*=temp;

60         temp%=mod;

61         n>>=1;

62     }

63     return ans;

64 }

65 

66 int main()

67 {

68     node tem;

69     tem.a[0][0]=0; tem.a[0][1]=1;

70     tem.a[1][0]=tem.a[1][1]=1;

71     while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)

72     {

73         node st=pow_m(tem,n);

74         printf("%I64d\n",(pow_M(a,st.a[0][0])*pow_M(b,st.a[1][0]))%mod);

75     }

76     return 0;

77 }
View Code

 

你可能感兴趣的:(HDU)