题目链接:https://www.luogu.org/problemnew/show/P1306
题意很清晰,数论推公式题。(推出来你就做出来了。推导过程我就不说了(其实我也不会逃))
1.gcd(f(n),f(m))=f(gcd(n,m))。(知道这个,下面就是矩阵快速幂水题了,求斐波那契第x项)
2.矩阵快速幂求斐波那契第x项
需要注意的是!先取余保留最后8位再计算公约数的话值就变了不对的。你先找出这个值在取余保留最后8位的话才对。(不信自己样例模拟一下就知道这是多么的错,然而还容易往这想)
1 #include <iostream> 2 using namespace std; 3 typedef long long ll; 4 const int mod=1e8; 5 const int maxn=3; 6 ll n,m,x; 7 struct jz//矩阵部分 8 { 9 ll a[maxn][maxn]; 10 }base,unit; 11 jz operator*(jz aa,jz bb) 12 { 13 jz c; 14 for(ll i=1;i<=maxn-1;i++) 15 { 16 for(ll j=1;j<=maxn-1;j++) 17 { 18 ll t=0; 19 for(ll k=1;k<=maxn-1;k++) t=(t%mod+aa.a[i][k]%mod*bb.a[k][j]%mod)%mod; 20 c.a[i][j]=t%mod; 21 } 22 } 23 24 return c; 25 } 26 27 void Init()//初始化 28 { 29 for(int i=1;i<=maxn-1;i++) unit.a[i][i]=i;//单位矩阵 30 31 base.a[1][1]=1; base.a[1][2]=1;//底数矩阵 32 base.a[2][1]=1; base.a[2][2]=0; 33 } 34 35 ll gcd(ll a,ll b)//最大gcd 36 { 37 return b?gcd(b,a%b):a; 38 } 39 40 jz Qpow(jz base,ll b)//快速幂 41 { 42 jz r=unit; 43 while(b) 44 { 45 if(b&1) r=r*base; 46 base=base*base; 47 b>>=1; 48 } 49 50 return r; 51 } 52 53 int main() 54 { 55 ios::sync_with_stdio(false); cin.tie(0); 56 57 cin>>n>>m; 58 59 x=gcd(n,m); 60 if(x==0) cout<<'0'<<endl; 61 else if(x==1) cout<<'1'<<endl; 62 else if(x==2) cout<<'1'<<endl; 63 else 64 { 65 Init(); 66 jz ans=Qpow(base,x-2); 67 ll anss=(ans.a[1][1]*1+ans.a[1][2]*1)%mod;//注意取模,这里也会超.... 68 cout<<anss<<endl; 69 } 70 71 return 0; 72 }
完。