矩陣快速冪(共軛函式兩種遞推式)
阿新 • • 發佈:2018-11-11
題目連結:https://cn.vjudge.net/contest/261339#problem/B
AC1:ans= x(n)+y(n)*sqrt(6),所以,ans=x(n)+y(n)*sqrt(6)+(x(n)-y(n)*sqrt(6))-(x(n)-y(n)*sqrt(6))=2*x(n)-(x(n)-y(n)*sqrt(6)),可以推出
(x(n)-y(n)*sqrt(6))是大於0小於等於1的,所以ans= 2*x(n)-1。
AC程式碼1:
#include<iostream> #include<string> #include<cstring> #include<iomanip> #include<stdio.h> #include<cmath> using namespace std; # define mod 1024 # define ll long long struct Matrix { ll a[5][5]; Matrix operator *(Matrix t) { Matrix temp; for(ll i=1; i<=2; i++) { for(ll j=1; j<=2; j++) { temp.a[i][j]=0; for(ll k=1; k<=2; k++) { temp.a[i][j]+=((a[i][k]%mod)*(t.a[k][j]%mod)+mod)%mod; } } } return temp; } }; ll quickpow(Matrix t,ll t1) { t1--; Matrix temp=t; while(t1) { if(t1&1)temp=temp*t; t=t*t; t1>>=1; } ll x=(5*temp.a[1][1]%mod+2*temp.a[2][1]%mod)%mod; return (x*2-1)%mod; } int main() { ll T; scanf("%lld",&T); while(T--) { Matrix temp; temp.a[1][1]=5; temp.a[1][2]=2; temp.a[2][1]=12; temp.a[2][2]=5; ll n; scanf("%lld",&n); if(n==1)printf("%lld\n",9); else { ll ans=quickpow(temp,n-1); printf("%lld\n",ans); } } return 0; }
方法二:這個推得方法就和我的上一篇部落格的推理方法是一樣的了。直接寫矩陣
{10 -1}
{1 0}.
AC程式碼2:
#include<iostream> #include<string> #include<cstring> #include<iomanip> #include<cmath> #include<stdio.h> #include<algorithm> #include<queue> using namespace std; # define ll long long # define maxn # define inf 0x3f3f3f3f # define mod 1024 struct Matrix { ll a[5][5]; Matrix operator *(Matrix t) { Matrix temp; for(int i=1; i<=2; i++) { for(int j=1; j<=2; j++) { temp.a[i][j]=0; for(int k=1; k<=2; k++) { temp.a[i][j]+=((a[i][k]%mod)*(t.a[k][j]%mod)+mod)%mod; } } } return temp; } }; ll quickpow(Matrix t,ll t1) { Matrix temp=t; t1--; while(t1) { if(t1&1)temp=temp*t; t=t*t; t1>>=1; } return (temp.a[1][1]*10%mod+temp.a[1][2]*2%mod+mod)%mod-1; } int main() { ll T; scanf("%lld",&T); while(T--) { Matrix t; t.a[1][1]=10; t.a[1][2]=-1; t.a[2][1]=1; t.a[2][2]=0; ll n; scanf("%lld",&n); if(n==1)printf("%lld\n",9); else { ll ans=quickpow(t,n-1); printf("%lld\n",ans); } } return 0; }