POJ - 3734 Blocks 指数生成函数

传送门

文章目录

题意:

一段长度为 n n n的序列,你有红黄蓝绿四种颜色的砖块,问你铺砖的方案数,每块砖长度为 1 1 1,其中红黄颜色个数必须为偶数。

思路:

考虑多重集合排列数:
在这里插入图片描述
所以我们构造四种颜色的指数生成函数,并转换成封闭式:
f 红 ( x ) = f 黄 ( x ) = 1 + x 2 2 ! + x 4 4 ! + . . . = e x + e − x 2 f_{红}(x)=f_{黄}(x)=1+\frac{x^2}{2!}+\frac{x^4}{4!}+...=\frac{e^x+e^{-x}}{2} f(x)=f(x)=1+2!x2+4!x4+...=2ex+ex
f 蓝 ( x ) = f 绿 ( x ) = 1 + x 1 ! + x 2 2 ! + . . . = e x f_{蓝}(x)=f_{绿}(x)=1+\frac{x}{1!}+\frac{x^2}{2!}+...=e^x f(x)=f绿(x)=1+1!x+2!x2+...=ex

将其乘起来得封闭式
G = e 2 x ∗ e 2 x + e − 2 x + 2 4 = e 4 x + 2 e 2 x + 1 4 G=e^{2x}*\frac{e^{2x}+e^{-2x}+2}{4}=\frac{e^{4x}+2e^{2x}+1}{4} G=e2x4e2x+e2x+2=4e4x+2e2x+1
再将封闭式展开
e x = ∑ i ≥ 0 x i i ! e^x=\sum_{i\ge0}\frac{x^i}{i!} ex=i0i!xi,得 e k x = ∑ i ≥ 0 k i x i i ! e^{kx}=\sum_{i\ge0}\frac{k^ix^i}{i!} ekx=i0i!kixi,即 G = 1 4 + ∑ i ≥ 0 ( 4 i + 2 i + 1 ) ∗ x i i ! 4 G=\frac{1}{4}+\frac{\sum_{i\ge0}(4^i+2^{i+1})*\frac{x^i}{i!}}{4} G=41+4i0(4i+2i+1)i!xi,取指数为 n n n的项,得系数 4 n + 2 n + 1 4 ∗ n ! \frac{4^n+2^{n+1}}{4*n!} 4n!4n+2n+1,可以将常数项忽略,再乘上多重集合排列数的分子 n ! n! n! 4 n + 2 n + 1 4 = 4 n − 1 + 2 n − 1 \frac{4^n+2^{n+1}}{4}=4^{n-1}+2^{n-1} 44n+2n+1=4n1+2n1,答案即为 4 n − 1 + 2 n − 1 4^{n-1}+2^{n-1} 4n1+2n1,快速幂直接算一下即可。

// Problem: Blocks
// Contest: Virtual Judge - POJ
// URL: https://vjudge.net/problem/POJ-3734
// Memory Limit: 65 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=1000010,mod=10007,INF=0x3f3f3f3f;
const double eps=1e-6;

LL qmi(LL a,LL b) {
	LL ans=1;
	while(b) {
		if(b&1) ans=ans*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ans%mod;
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);	

	int _; cin>>_;
	while(_--) {
		int n; cin>>n;
		cout<<((1ll*qmi(4,n-1)+qmi(2,n-1))%mod)<<endl;
	}




	return 0;
}
/*

*/









  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值