hdu 5895(矩阵快速幂+欧拉函数)
Posted AC菜鸟机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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))
反正比赛没做出来.
#include <bits/stdc++.h> #define LL long long using namespace std; struct Maxtri{ LL v[2][2]; Maxtri(){memset(v,0,sizeof(v));} }ori; LL n, y, x, s, mod ; Maxtri mult(Maxtri a,Maxtri b){ Maxtri temp; for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ for(int k=0;k<2;k++){ temp.v[i][j] = (temp.v[i][j]+(a.v[i][k]*b.v[k][j])%mod)%mod; } } } return temp; } LL pow_mod(Maxtri a,LL n){ if(n==0) return 0; if(n==1) return 1; if(n==2) return 2; n-=2; Maxtri ans; for(int i=0;i<2;i++){ ans.v[i][i] = 1; } while(n){ if(n&1) ans = mult(ans,a); a = mult(a,a); n>>=1; } return (ans.v[0][0]*2+ans.v[0][1])%mod; } LL pow_mod1(LL a,LL n,LL mod){ LL ans = 1; while(n){ if(n&1) ans = ans*a%mod; a = a*a%mod; n>>=1; } return ans; } LL Phi(LL x) { LL ans = x; for(LL i=2LL; i*i<=x; i++) { if(x % i == 0) { ans -= ans/i; while(x % i == 0) x /= i; } } if(x > 1) ans -= ans/x; return ans; } int main(){ ori.v[0][0] = 2,ori.v[0][1] = 1; ori.v[1][0] = 1,ori.v[1][1] = 0; int tcase; scanf("%d",&tcase); while(tcase--){ scanf("%lld%lld%lld%lld",&n, &y, &x, &s); s++; LL phi = 2*Phi(s); mod = 2*phi; LL fn = pow_mod(ori,n*y); LL fn1 = pow_mod(ori,n*y+1); LL ans = ((fn*fn1)%mod/2); ans+=phi; printf("%lld\n",pow_mod1(x,ans,s)%s); } return 0; }
以上是关于hdu 5895(矩阵快速幂+欧拉函数)的主要内容,如果未能解决你的问题,请参考以下文章
hdu 5895 Mathematician QSC 指数循环节+矩阵快速幂
HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)——2016 ACM/ICPC Asia Regional Shenyang Online