題目鏈接
題目描述:
其中,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;
}