HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂

装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次。公式比较好推。f[n] = f[n-1]*f[n-2]。然后a和b系数都是呈斐波那契规律增长的。需要先保存下来指数。但是太大了。在这里不能用小费马定理。要用降幂公式取模、
(A^x)%C=A^(x%phi(C)+phi(C))%C(x>=phi(C)) Phi[C]表示不大于C的数中与C互质的数的个数,可以用欧拉函数来求。

矩阵快速幂也不熟、。觉得很难。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #define N 1000005
  5
  6 int visit[N],prime[N],K;
  7 long long P,Phi;
  8
  9 struct matrix
 10 {
 11     long long A[2][2];
 12 };
 13
 14 void intt()   // 找出1000000以内的素数
 15 {
 16     int i,j;
 17     memset(visit,0,sizeof(visit));
 18     for(i=2; i<=1000; i++)
 19     {
 20         if(visit[i]==0)
 21         {
 22             for(j=i+i; j<=1000000; j+=i)
 23             {
 24                 visit[j]=1;
 25             }
 26         }
 27     }
 28     K=0;
 29     for(j=2; j<=1000000; j++)
 30         if(visit[j]==0) prime[++K]=j;
 31 }
 32
 33 matrix power(matrix ans1,matrix ans2)  // 矩阵乘法
 34 {
 35     int i,j,k;
 36     matrix ans;
 37     for(i=0; i<=1; i++)
 38     {
 39         for(j=0; j<=1; j++)
 40         {
 41             ans.A[i][j]=0;
 42             for(k=0; k<=1; k++)
 43             {
 44                 ans.A[i][j]+=ans1.A[i][k]*ans2.A[k][j];
 45                 if(ans.A[i][j]>Phi)
 46                 {
 47                     ans.A[i][j]=ans.A[i][j]%Phi+Phi;
 48                 }
 49             }
 50         }
 51     }
 52     return ans;
 53 }
 54
 55 matrix mod(matrix un, long long k)  // 求矩阵的k次幂
 56 {
 57     matrix ans;
 58     ans.A[0][0]=1;
 59     ans.A[0][1]=0;
 60     ans.A[1][0]=0;
 61     ans.A[1][1]=1;
 62     while(k)
 63     {
 64         if(k%2) ans=power(ans,un);
 65         un=power(un,un);
 66         k/=2;
 67     }
 68     return ans;
 69 }
 70
 71 long long mod1(long long a, long long k)  //求(a^k)%p
 72 {
 73     long long ans;
 74     ans=1;
 75     while(k)
 76     {
 77         if(k%2)
 78         {
 79             ans=ans*a;
 80             ans%=P;
 81         }
 82         a=a*a;
 83         a%=P;
 84         k/=2;
 85     }
 86     return ans%P;
 87 }
 88
 89 int main()
 90 {
 91     int i,ncase,t;
 92     long long a,b,aa,bb,n,num,num1,num2;
 93     matrix init,ans;
 94
 95     intt();
 96     scanf("%d",&ncase);
 97
 98     for(t=1; t<=ncase; t++)
 99     {
100         scanf("%I64d%I64d%I64d%I64d",&a,&b,&P,&n);
101         printf("Case #%d: ",t);
102         if(n==1)
103         {
104             printf("%I64d\n",a%P);
105             continue;
106         }
107         else if(n==2)
108         {
109             printf("%I64d\n",b%P);
110             continue;
111         }
112         else if(n==3)
113         {
114             printf("%I64d\n",a*b%P);
115             continue;
116         }
117         if(P==1)
118         {
119             printf("0\n");
120             continue;
121         }
122
123         // 初始化求斐波那契数的初始矩阵
124         init.A[0][0]=0;
125         init.A[0][1]=1;
126         init.A[1][0]=1;
127         init.A[1][1]=1;
128         //  A^B % C = A ^ ( B % phi[C] + phi[C] ) %C  ( B >= phi[C] ) ,phi[C]表示与C互质的数的个数
129         Phi=1;
130         num=P;
131
132         for(i=1; i<=K; i++)
133         {
134             if(prime[i]>P) break;
135             if(P%prime[i]==0)
136             {
137                 Phi*=(prime[i]-1);
138                 num/=prime[i];
139             }
140         }
141         //phi[C]=C*(1-1/p1)*(1-1/p2)*...*(1-1/pt);p1,p2,...pt表示C的素因子
142         Phi*=num;//Phi表示phi[C] 在这里c = p
143
144
145         ans=mod(init,n-3);//求指数
146         num1=ans.A[1][1];//a的指数
147         num2=ans.A[0][1]+ans.A[1][1];//b的指数    求b的指数不是已经溢出了吗。???
148         if(num2>Phi) num2=num2%Phi+Phi;
149
150         aa=mod1(a,num1);//a^num1%p;
151         bb=mod1(b,num2);//b^num2%p;
152
153         printf("%I64d\n",aa*bb%P);
154     }
155     return 0;
156 }

时间: 2024-10-26 16:21:03

HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂的相关文章

hdu 5895(矩阵快速幂+欧拉函数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895 f(n)=f(n-2)+2*f(n-1) f(n)*f(n-1)=f(n-2)*f(n-1)+2*f(n-1)*f(n-1); 2*f(n-1)*f(n-1)=f(n)*f(n-1)-f(n-2)*f(n-1); 累加可得 g(n) = f(n)*f(n+1)/2 然后这个公式:A^x % m = A^(x%phi(m)+phi(m)) % m (x >= phi(m)) 反正比赛没做出来.

BZOJ1408 NOI2002 Robot 快速幂+欧拉函数

题意:分别求所有质因数都不同且质因数个数为奇数个.偶数个的数的欧拉函数和,和质因数存在重复的数的欧拉函数和 题解: 说书题……前面一大串就是用一种比较有趣的语言定义欧拉函数. 显然我们只需要求出所有军人ans1和政客ans2,然后用求得的M减去独立数和就是学者的独立数和了. 由于善良的出题人已经帮我们把M给质因分解了,因此我们假定当前已经得到了ans1和ans2,那么根据欧拉函数的定义,ans1'=ans1+ans2*(p-1),ans2'=ans2+ans1*(p-1),因为新加入的质因子会让

Super A^B mod C 快速幂+欧拉函数降幂

uper A^B mod C Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000). Input There are

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

1408: [Noi2002]Robot|快速幂|欧拉函数

真是一道神题,语文渣渣表示已经给题意描述跪烂了.. 独立数显然就是欧拉函数φ 然后政客军人他们的分解成的奇素数的指数显然都是1,最初的思想就是暴力枚举只有1个奇函数的情况,2个,3个----这样显然是会超时,可以发现欧拉函数是满足积性的,所以可以放到一起乘起来算用一种类似于DP的"前缀和"的思想来做 ans1表示当前有奇数个奇数质因子的"前缀和" ans2表示当前有偶数个奇数质因子的"前缀和" 然后学者的独立数可以用总和减去前两个的和,因为欧拉函

hdu--4549--费马小定理&amp;快速幂&amp;欧拉函数

这题 蛮复杂的. 我自己做的时候 无法处理完 最后一步公式的转换 后来看到别人说这是 费马小定理 与 欧拉函数的思想下的转换 可是 我自己还推导不出来啊... 首先 你要发现f[n]=a^x * b^y其实指数x 与 y是fib数列中的f[n-1]与f[n]项( n>=1 并且数列是0 1 1 2 3 5 8 ...) 那么 其实题目就转换成了 f[n] = a^fib[n-1] * b^fib[n] % mod; 这边 不必要对于 a^fib[n-1]与 b^fib[n] 单独再在括号进行取模

E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

题目链接: https://codeforces.com/contest/1182/problem/E 题目大意:  f(x)=c^(2x−6)⋅f(x−1)⋅f(x−2)⋅f(x−3)    for x≥4x≥4. 给你f1,f2,f3,n,c.求第n项的结果. 具体思路: 看到递推式想到用矩阵快速幂优化:但是如果都是乘法的话,是无法化成矩阵相乘的形式的.然后就开始想怎么将乘法转换成加法.推了一个多小时也没有推出来.. 具体的解题过程如下: 对于每一项,这一项里面包含的f1 和 f2 和 f3

hdu 2814 快速求欧拉函数

1 /** 2 大意: 求[a,b] 之间 phi(a) + phi(a+1)...+ phi(b): 3 思路: 快速求欧拉函数 4 **/ 5 6 #include <iostream> 7 #include <cstring> 8 using namespace std; 9 #define Max 3000000 10 11 long long phi[Max+5]; 12 int prime[Max/10]; 13 bool flag[Max+5]; 14 15 void

POJ2478_Farey Sequence【快速求欧拉函数】

Farey Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12377 Accepted: 4808 Description The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1