hdu3221 扩展欧拉定理(降幂大法)

来源:互联网 发布:衣服批发软件哪个好 编辑:程序博客网 时间:2024/06/05 19:09
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3221
题解:首先很容易发现递推公式fn=fn-1*fn-2;写出前几项a,b,a*b,a*b^2,a^2*b^3,a^3*b^5;易发现a,b的指数为斐波那契数列。但是当N大一点时,斐波那契数列便变得非常大。那么此时得用扩展欧拉定理降幂。
a^b%p=a^(b%phi(p)+phi(p))%p   b>=phi(p)(不要求a与p互质)
特别要主要使用条件, b>=phi(p)
接着用矩阵快速幂求斐波那契数列,再快速幂求答案即可。

代码如下:

#include <bits/stdc++.h>#define ll long longusing namespace std;const int maxn = 1000000 + 10;ll MOD = 1e9 + 7;ll a,b,n;ll phi[maxn];struct Matrix{ll n, m;ll mat[3][3];Matrix(ll a = 0, ll b = 0):n(a),m(b) {memset(mat,0,sizeof(mat));}void init(ll a, ll b) {n = a;m = b;}Matrix operator *(const Matrix & x){Matrix ans;ans.init(n,x.m);for(int i = 1;i <= n;i++){for(int j = 1;j <= x.m;j++){for(int k = 1;k <= m;k++){ans.mat[i][j] += mat[i][k] * x.mat[k][j];if(ans.mat[i][j] > phi[MOD]) ans.mat[i][j] = ans.mat[i][j] % phi[MOD] + phi[MOD];}}}return ans;}};Matrix q_pow(Matrix x, ll k){Matrix ret;ret.init(2,2);ret.mat[1][1] = ret.mat[2][2] = 1;while(k > 0){if(k & 1) ret = ret * x;x = x * x;k >>= 1;}return ret;}ll q_pow(ll x, ll k){ll ret = 1;while(k > 0){if(k & 1) ret = ret * x % MOD;x = x * x % MOD;k >>= 1;}return ret;}int primes[maxn],pcnt;void get_phi(int n){memset(phi,0,sizeof(phi));phi[1] = 1;int t = 0;for(int i = 2;i <= n;i++){if(!phi[i]) {primes[++pcnt] = i;phi[i] = i - 1;}for(int j = 1;j <= pcnt;j++){t = primes[j];if(i * t > n) break;if(i % t == 0){phi[i * t] = phi[i] * t;break;}else phi[i * t] = phi[i] * (t - 1);}}}int main(){get_phi(maxn - 10);int kase;scanf("%d",&kase);int T = 0;while(kase--){printf("Case #%d: ",++T);scanf("%I64d%I64d%I64d%I64d",&a,&b,&MOD,&n);if(MOD == 1) {printf("0\n");continue;}if(n == 1) {printf("%I64d\n",a % MOD);continue;}if(n == 2) {printf("%I64d\n",b % MOD);continue;}Matrix tmp;tmp.init(2,2);tmp.mat[1][1] = 0;tmp.mat[1][2] = 1;tmp.mat[2][1] = 1;tmp.mat[2][2] = 1;Matrix p = Matrix(1,2);p.mat[1][1] = 1;p.mat[1][2] = 1;tmp = q_pow(tmp, n - 3);p = p * tmp;ll ans = 1;ans *= q_pow(a,p.mat[1][1]);ans *= q_pow(b,p.mat[1][2]);ans %= MOD;printf("%I64d\n",ans);}return 0;}


阅读全文
0 0