P1306 斐波那契公约数:https://www.luogu.org/problemnew/show/P1306
这道题目就是求第n项和第m项的斐波那契数字,然后让这两个数求GCD,输出答案的后8位;
思路:
1/gcd(F[n],F[m])=F[gcd(n,m)]。所以先求出gcd(n,m),然后构造斐波那契数列的矩阵快速幂。
#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> using namespace std; //#pragma GCC optimize(3) //#pragma comment(linker, "/STACK:102400000,102400000") //c++ #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << " "; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; typedef pair<ll ,ll > pll; typedef pair<int ,int > pii; typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second //#define endl ' ' #define OKC ios::sync_with_stdio(false);cin.tie(0) #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行 #define REP(i , j , k) for(int i = j ; i < k ; ++i) //priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //2147483647 const ll nmos = 0x80000000; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; //18 const int mod = 1e8; const double esp = 1e-8; const double PI=acos(-1.0); template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } /*-----------------------showtime----------------------*/ struct mat{ int r,c; ll a[4][4]; }; int gcd(int a,int b){ if(b == 0)return a; return gcd(b, a%b); } mat mul(mat a,mat b){ mat tmp = a; tmp.a[0][0] = tmp.a[0][1] = tmp.a[1][0] = tmp.a[1][1] = 0; for(int i=0; i< a.r; i++){ for(int j=0; j<b.c;j++){ for(int k=0; k<a.c; k++){ tmp.a[i][j] += a.a[i][k] * b.a[k][j]; tmp.a[i][j] %= mod; } } } return tmp; } int ksm(int n){ mat ans,ic; ic.r = ic.c = 2; ic.a[0][0] = ic.a[0][1] = ic.a[1][0] = 1; ic.a[1][1] = 0; ans.r = 1,ans.c = 2; ans.a[0][0] = ans.a[0][1] = 1; while(n > 0){ if(n&1) ans = mul(ans, ic); ic = mul(ic,ic); n>>=1; } return ans.a[0][0]; } int main(){ int a,b; scanf("%d%d", &a, &b); int n = gcd(a, b); if(n <=2)cout<<1<<endl; else cout<<ksm(n-2)<<endl; return 0; }