参见五边形定理。。
http://en.wikipedia.org/wiki/Partition_的生成函数是
- (1)
-
再
利用五边形数定理可得到以下的展开式:
- (2)
- 将(2)式带入(1)式,并乘到(1)式的左边,进行展开,合并同类项,根据非常数项的系数为0!!
- 即将 生成函数配合 五边形数定理,可以得到以下的递归关系式
-
#include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<string> #include<cstring> #include<set> #include<map> #include<list> #include<queue> #include<vector> #define tree int o,int l,int r #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r #define lo o<<1 #define ro o<<1|1 #define ULL unsigned long long #define LL long long #define UI unsigned int #define inf 0x7fffffff #define eps 1e-7 #define M 1000000007 #define N 100001 using namespace std; int T,n,m,k,t,maxv; LL p[N]; void init()// { p[0]=p[1]=1; for(int i=2; i<N; i++) { for(int j=1,k=1;; j++,k=-k) { int s=j*(j*3-1)/2; if(i-s>=0) p[i]=(p[i]+p[i-s]*k)%M; else break; s=j*(j*3+1)/2; if(i-s>=0) p[i]=(p[i]+p[i-s]*k)%M; else break; } while(p[i]<0)p[i]+=M;//WA!!!负值 } } int main() { #ifndef ONLINE_JUDGE freopen("ex.in","r",stdin); #endif int ncase=0; scanf("%d",&T); init(); // while(scanf("%d",&n)==1) while(T--) { scanf("%d",&n); printf("%I64d\n",p[n]); } return 0; }
-
-