HDU 3221 Brute-force Algorithm
2015-01-30 21:29
190 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3221
思路:
稍微开个脑洞想想,就能发现递推式是f(n)=f(n-1)*f(n-2),再想想就能想到可通过先计算a用了多少次,b用了多少次来计算,最后套一个快速幂来计算f(n),在计算a用了多少次的时候又可以发现,a的次数其实是一个斐波那契数,但是在计算a的次数的时候会发现这个次数会爆long long并且不能简单的来用P进行取模,怎么办呢? 怎么办呢? 想了好久后来才知道这个地方有一个公式:
(a^b)%mo=(a^(b%phi[mo]+phi[mo]))%mo b>=phi[mo]
用这个公式在矩阵快速幂的时候对b进行取模就好(ps:不是直接对phi[mo]取模~~~)
code:
思路:
稍微开个脑洞想想,就能发现递推式是f(n)=f(n-1)*f(n-2),再想想就能想到可通过先计算a用了多少次,b用了多少次来计算,最后套一个快速幂来计算f(n),在计算a用了多少次的时候又可以发现,a的次数其实是一个斐波那契数,但是在计算a的次数的时候会发现这个次数会爆long long并且不能简单的来用P进行取模,怎么办呢? 怎么办呢? 想了好久后来才知道这个地方有一个公式:
(a^b)%mo=(a^(b%phi[mo]+phi[mo]))%mo b>=phi[mo]
用这个公式在矩阵快速幂的时候对b进行取模就好(ps:不是直接对phi[mo]取模~~~)
code:
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> using namespace std; typedef long long LL; typedef vector<LL> vec; typedef vector<vec> mat; LL mo,mod; LL mod_pow(LL x,LL n) { LL res=1; while(n>0){ if(n&1) res=res*x%mo; x=x*x%mo; n>>=1; } return res; } mat mul(mat &A,mat &B) { mat C(A.size(),vec(B[0].size())); for(int i=0;i<A.size();i++){ for(int k=0;k<B.size();k++){ for(int j=0;j<B[0].size();j++){ C[i][j]=C[i][j]+A[i][k]*B[k][j]; if(C[i][j]>mod) C[i][j]=C[i][j]%mod+mod; } } } return C; } mat pow(mat A,LL n) { mat B(A.size(),vec(A.size())); for(int i=0;i<A.size();i++) B[i][i]=1; while(n>0){ if(n&1) B=mul(B,A); A=mul(A,A); n>>=1; } return B; } LL euler(LL x) { LL i, res = x; for (i = 2; i*i <= x; i++) { if (x%i == 0) { res = res / i*(i - 1); while (x%i == 0) x /= i; } } if (x > 1) res = res / x*(x - 1); return res; } int main() { LL a,b,n,m1,m2,res; int T; scanf("%d",&T); for(int kk=1;kk<=T;kk++){ scanf("%I64d%I64d%I64d%I64d",&a,&b,&mo,&n); printf("Case #%d: ",kk); //if(mo==1) printf("0\n"); //else if(n==1) printf("%I64d\n",a%mo); //else if(n==2) printf("%I64d\n",b%mo); //else{ mod=euler(mo); mat A(2,vec(2)); A[0][0]=A[0][1]=1; A[1][0]=1;A[1][1]=0; A=pow(A,n-1); m1=A[1][1]; if(m1>=mod) m1=m1%mod+mod; m2=A[1][0]; //cout<<m1<<" "<<m2<<endl; if(m2>=mod) m2=m2%mod+mod; res=(mod_pow(a,m1)*mod_pow(b,m2))%mo; printf("%I64d\n",res); // } } return 0; }
相关文章推荐
- hdu 3221 Brute-force Algorithm
- Hdu 3221 Brute-force Algorithm (矩阵 欧拉定理降幂)
- SPOJ 5152 Brute-force Algorithm EXTREME && HDU 3221 Brute-force Algorithm 快速幂,快速求斐波那契数列,欧拉函数,同余 难度:1
- hdu 3221 Brute-force Algorithm 指数循环节
- HDU 3221 Brute-force Algorithm
- HDU 3221 Brute-force Algorithm
- HDU 3221Brute-force Algorithm(降幂公式 神似hdu4549)
- hdu 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm
- Brute-force Algorithm [HDU 3221]
- hdu 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)
- HDU 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm(快速幂取模,矩阵快速幂求fib)
- HDU 3221 Brute-force Algorithm(指数降幂公式)
- HDU 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm
- HDU 3221 Brute-force Algorithm(欧拉公式降幂)
- HDU 3221 Brute-force Algorithm(矩阵求fibnacci,指数取模)