POJ3734 Blocks

傳送門


最近開始增強生成函數。c++

學完級數後,感受生成函數就是將幾個級數相乘,而後收斂成某個函數後進行化簡,最後再用經常使用級數展開式或者廣義二項式定理展開,獲得新的級數,那麼\(m\)次項的係數就是和爲\(m\)的方案數。


對於這道題,由於有選擇順序的不一樣,因此要用指數型生成函數。藍,黃色的生成函數都是\(e^x\),紅,綠色只能是偶數,那就是\(f(x)=\sum\limits_{n=0}^{\infty} \frac{(2n)!}{x^{2n}}=\frac{e^x+e^{-x}}{2}\).ide

將上述四個生成函數相乘,就是總方案數的生成函數\(F(x)\),函數

 

\[\begin{align*} F(x) &= e^{2x} * (\frac{e^x+e^{-x}}{2})^2\\ &= \frac1{4}(e^{4x}+2e^{2x}+1)\\ &= \frac1{4}[\sum_{n=0}^{\infty} \frac1{n!}(4x)^n+2\sum_{n=0}^{\infty}\frac1{n!}(2x)^n+1]\\ \end{align*}\]

 

那麼\(n\)次方項的係數就是\(\frac{4^n+2^{n+1}}{4n!}\),再乘以\(n!\)即答案。ui

#include<cstdio>
using namespace std;
typedef long long ll;
const ll mod = 10007;

ll quickpow(ll a, ll b)
{
	ll ret = 1;
	for(; b; b >>= 1, a = a * a % mod)
		if(b & 1) ret = ret * a % mod;
	return ret;
}

int main()
{
	int T; scanf("%d", &T); 
	ll inv4 = quickpow(4, mod - 2);
	while(T--)
	{
		int n; scanf("%d", &n);
		printf("%lld\n", (quickpow(4, n) + quickpow(2, n + 1)) % mod * inv4 % mod);
	}
	return 0;
}
相關文章
相關標籤/搜索