水題(water) 斐波那契數列(矩陣快速冪)

題目鏈接

題目描述:

在這裏插入圖片描述其中,f(1)=1;f(2)=1;Z皇后的方案數:即在Z×Z的棋盤上放置Z個皇后,使其互不攻擊的方案數。 在這裏插入圖片描述

輸入描述:

輸入數據共一行,兩個正整數x,m,意義如“題目描述”。

輸出描述:

一個正整數k,表示輸出結尾0 的個數或者放置皇后的方案數

輸入:

375 16

輸出:

14200

題中有三個需要解決的問題,x是否屬於斐波那契數列,x!在m進制下末尾0的個數,N皇后問題。
第一個問題用矩陣快速冪和二分解決。
第二個問題用分解質因數解決。
第三個問題用打表(省事)。

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
const LL  INF = 0x3f3f3f3f3f3f3f3f;

int bit[14] = {0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712}; // N queen type

struct Matrix{ // Matrix class
	LL m[3][3];
	Matrix() {memset(m, 0, sizeof(m));}
};
Matrix multi(Matrix a, Matrix b){ // Matrix multiplication
	Matrix res; 
	for(int i = 1; i <= 2; ++ i)
		for(int j = 1; j <= 2; ++ j)
			for(int k = 1; k <= 2; ++ k)
				res.m[i][j] += a.m[i][k] * b.m[k][j];
	return res;
}
LL fastm(int n){ // Matrix fast power 
	if (n <= 0) return 1ll;
	Matrix res; res.m[1][1] = res.m[2][2] = 1;
	Matrix a; a.m[1][1] = a.m[1][2] = a.m[2][1] = 1;
	while(n){
		if (n & 1) res = multi(res, a);
		n >>= 1;
		a = multi(a, a);
	}
	return res.m[1][1] + res.m[1][2];
} 
inline bool dich(int l, int r, LL x) { //Binary Search —— Fibonacci sequence
	if (l == r) return fastm(l - 2) == x;
	int mid = l + r >> 1;
	if (fastm(mid - 2) < x) return dich(mid + 1, r, x);
	return dich(l, mid, x);
}

int main() {
	LL x; int m; scanf("%lld%d", &x, &m);
	if (dich(1, 90, x)) { 
		LL cnt = INF;   
		for(int i = 2; i <= m; ++ i) { //Factorization prime factor
			int a = 0;
			if (i*i > m) i = m;
			while(m % i == 0) {
				m /= i;
				a ++;
			}
			if (a == 0) continue;
			LL temp = x, sum = 0;
			while(temp) {
				sum += temp /= i;
			}
			if (cnt > sum/a) cnt = sum/a;
		}
		printf("%lld\n", cnt);
	}
	else { 
		int t = x % min(m, 13) + 1;
		printf("%d\n", bit[t]); 
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章