1. 程式人生 > >crash的遊戲

crash的遊戲

題目大意:求: i=0m(mi)(n+m2ik)\sum_{i=0}^m\binom mi\binom {n+m-2i}{k} m109,k300,m+kn109m\le10^9,k\le300,m+k\le n\le10^9。500組資料。 題解: 直接暴做。 首先注意到(xk)\binom x k是一個關於xxkk次多項式,設(xk)=i=0kaixi\binom xk=\sum_{i=0}^ka_ix^i,則: i=0m(mi)(n+m2ik)=i=0m(mi)j=0kaj(n+

m2i)j=i=0kaij=0m(mj)(n+m2j)i=i=0kaij=0m(mj)t=0i(it)(n+m)t(2j)it=i=0kait=0i(it)(n+m)t(2)itj=0m(mj)jit=i=0kait=0i(it)(n+m)t(2)itfit(m)\sum_{i=0}^m\binom mi\binom {n+m-2i}{k}\\ =\sum_{i=0}^m\binom mi\sum_{j=0}^k a_j(n+m-2i)^j\\= \sum_{i=0}^ka_i\sum_{j=0}^m\binom mj(n+m-2j)^i\\= \sum_{i=0}^ka_i\sum_{j=0}^m\binom mj\sum_{t=0}^i\binom it(n+m)^t(-2j)^{i-t}\\ =\sum_{i=0}^ka_i\sum_{t=0}^i\binom it(n+m)^t(-2)^{i-t}\sum_{j=0}^m\binom mjj^{i-t}\\ =\sum_{i=0}^ka_i\sum_{t=0}^i\binom it(n+m)^t(-2)^{i-t}f_{i-t}(m)
其中: fk(n)=i=0n(ni)ik=i=0n(ni)j=0kS(k,j)(ij)j!=i=0kS(k,i)i!j=0n(nj)(ji)=i=0kS(k,i)i!(ni)2nif_k(n)=\sum_{i=0}^n\binom nii^k \\=\sum_{i=0}^n\binom ni\sum_{j=0}^kS(k,j)\binom ijj!\\ =\sum_{i=0}^kS(k,i)i!\sum_{j=0}^n\binom nj\binom ji\\ =\sum_{i=0}^kS(k,i)i!\binom ni2^{n-i}
可以在O(k)O(k)時間內計算,其中S(k,i)S(k,i)為第二類斯特林數。 綜上,fk(n),S(k,i),{ak}f_k(n),S(k,i),\{a_k\}均可在O(k2)O(k^2)時間內求出。 (實際上,關於fk(n)f_k(n),可以使用一些關於生成函式的技巧得知其是一個O(k)O(k)次多項式與2n2^n的乘積,可以使用拉格朗日插值在O(k2)O(k^2)時間內算出單項(所以說好像沒啥用)) 總之這樣就做完了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define mod 1000000007
#define lint long long
#define gc getchar()
#define N 310
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline int inn()
{
	int x,ch;while((ch=gc)<'0'||ch>'9');
	x=ch^'0';while((ch=gc)>='0'&&ch<='9')
		x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int st[N][N],fac[N],facinv[N],inv[N],a[N],npm[N],pm2[N],f[N];
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
const int inv2=fast_pow(2,mod-2);
inline int prelude(int n)
{
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=(lint)fac[i-1]*i%mod;
	facin