题意:n 个方块排成一排,用蓝黄红绿 4 种颜色涂色。要求涂红和绿的方块个数都为偶数,问有多少种涂色方案。
只要推导出通项公式即可:
首先将这排方框分成两个部分: 1.用蓝黄两种颜色上色 2.用红绿两种颜色上色。
前面的部分上色的方法数:2^(n-k)。(k 为偶数,k > 0)其他部分上色的方法数位:C(k,0)+C(k,2)+…C(K,4)+C(k,k) = 2^(k-1).(二项式系数的偶数项之和与奇数项之和相等)
得出 K 个方框上红绿的方法数:2^(n-k) * 2^(k-1) = 2^(n -1).
所以
ans = C(n,0)*2^(n)+C(n,2)*2^(n-1)+C(n,4)*2^(n-1)+… C(n,k) *2^(n-1) ….
= 2^(n-1)* (2+C(n,2)+C(n,4)+… C(n,k) …)
= 2^(n-1) *( 1+C(n,0)+C(n,2)+C(n,4)+… C(n,k) …)
= 2^(n-1) *(1+2*(n-1) )
= 2^(n-1)+4^(n-1)
当 n=0,ans=0; 当 n=1,ans=2。
然后用快速幂优化。
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MOD = 10007;
int n;
long long quickmod(long long a, long long n, long long MOD){
long long r = 1;
while(n){
if(n&1){
r = (a*r)%MOD;
}
a = (a*a)%MOD;
n >>= 1;
}
return r;
}
long long cal(){
long long ans = (quickmod(2, n-1, MOD)+quickmod(4, n-1, MOD))%MOD;
return ans;
}
int main(){
//freopen("a.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
if(n == 0) cout << "0" << endl;
else if(n == 1) cout << "2" << endl;
else cout << cal() << endl;
}
return 0;
}