[LOJ6671]EntropyIncreaser 与 Minecraft

对于原函数,我们尝试用生成函数进行刻画

每个维度上威力值对应的方案数的\(\tt OGF\)\(-1+\sum_{i=0}^\infty x^i=\frac{1+x}{1-x}\)

则由\(n\)维和的威力值产生的方案数为\(\left(\frac{1+x}{1-x}\right)^n\)

则我们要求的为前缀和,直接卷上\(1\over 1-x\)即可,为\((1+x)^n\over (1-x)^{n+1}\)

我们直接进行泰勒展开,对于\(\sum_{i=0}^\infty \frac{a_i}{i!}x^i\),我们不难得到\(a_i=(2n+1)a_{i-1}+(i-1)^2a_{i-2}\)

直接\(O(n)\)地递推即可

最后除以\(p!\)即可

但是我现在还不知道如何解出通项,以便用于\(O(polylog(n))\)地求解

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;
	char k;
	bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define ll long long
# define mod 1000000007
ll f[1000005],inv[1000005];
int s,n;
int main(){
	n=read,s=read;
	f[0]=1;f[1]=2*n+1;
	for(int i=2;i<=s;++i)
		f[i]=(f[i-1]*(2*n+1)+(i-1)*f[i-2]%mod*(i-1))%mod;
	inv[1]=1;ll t=1;
	for(int i=2;i<=s;++i)inv[i]=(mod-mod/i)*inv[mod%i]%mod,t=inv[i]*t%mod;
	cout<<f[s]*t%mod;
	return 0;
}
posted @ 2021-07-27 22:00  ファイナル  阅读(84)  评论(0)    收藏  举报