[Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)

时间:2023-03-09 05:18:38
[Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)

题目链接:http://www.ifrog.cc/acm/problem/1031

题意:6个水果中挑出n个,使得其中2个水果个数必须是偶数,问有多少种选择方法。

[Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)中0代表偶数,1代表奇数。分别代表两种水果的奇偶情况,有如下递推式:

[Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)

初始化的矩阵为:

[Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)

) 以后写题解就用latex编辑公式了QAQ

 #include <bits/stdc++.h>
using namespace std; typedef long long LL; const LL mod = (LL)1e9+;
const int maxn = ;
LL n;
typedef struct Matrix {
LL m[maxn][maxn];
int r;
int c;
Matrix(){
r = c = ;
memset(m, , sizeof(m));
}
} Matrix;
Matrix mul(Matrix m1, Matrix m2) {
Matrix ans = Matrix();
ans.r = m1.r;
ans.c = m2.c;
for(int i = ; i <= m1.r; i++) {
for(int j = ; j <= m2.r; j++) {
for(int k = ; k <= m2.c; k++) {
if(m2.m[j][k] == ) continue;
ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
}
}
}
return ans;
} Matrix quickmul(Matrix m, LL n) {
Matrix ans = Matrix();
for(int i = ; i <= m.r; i++) {
ans.m[i][i] = ;
}
ans.r = m.r;
ans.c = m.c;
while(n) {
if(n & ) {
ans = mul(m, ans);
}
m = mul(m, m);
n >>= ;
}
return ans;
} int main() {
// freopen("in", "r", stdin);
int T, _ = ;
scanf("%d", &T);
while(T--) {
scanf("%lld",&n);
Matrix a; a.r = ; a.c = ;
a.m[][] = ; a.m[][] = ; a.m[][] = ; a.m[][] = ;
Matrix p; p.r = , p.c = ;
p.m[][] = ; p.m[][] = ; p.m[][] = ; p.m[][] = ;
p.m[][] = ; p.m[][] = ; p.m[][] = ; p.m[][] = ;
p.m[][] = ; p.m[][] = ; p.m[][] = ; p.m[][] = ;
p.m[][] = ; p.m[][] = ; p.m[][] = ; p.m[][] = ;
Matrix q = quickmul(p, n-);
Matrix b = mul(q, a);
printf("Case #%d: %lld\n", _++,b.m[][]);
}
return ;
}