用五边形数解决整数拆分问题

典型例题:洛谷P6189

点击跳转

五边形数定理

∏ k = 1 ∞ ( 1 − x k ) = ∏ i = − ∞ ∞ ( − 1 ) i x 3 i 2 − i 2 \prod_{k=1}^\infin (1-x^k) = \prod _{i=-\infin} ^ \infin (-1)^i x ^{\frac{3i^2-i}{2}} k=1(1xk)=i=(1)ix23i2i

整数拆分

生成函数写出来:

∏ k = 1 ∞ 1 1 − x k \prod_{k=1}^\infin \frac{1}{1-x^k} k=11xk1

假设这个多项式是 a 0 x 0 + a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . a_0x^0 + a_1x^1 + a_2x^2 + a_3x^3 + ... a0x0+a1x1+a2x2+a3x3+...

现在二者结合

很显然
( a 0 x 0 + a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . ) ∏ k = 1 ∞ ( 1 − x k ) = 1 (a_0x^0 + a_1x^1 + a_2x^2 + a_3x^3 + ...) \prod_{k=1}^\infin (1-x^k) = 1 (a0x0+a1x1+a2x2+a3x3+...)k=1(1xk)=1

因此
( ∏ i = − ∞ ∞ ( − 1 ) i x 3 i 2 − i 2 ) ( a 0 x 0 + a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . ) = 1 (\prod _{i=-\infin} ^ \infin (-1)^i x ^{\frac{3i^2-i}{2}} ) (a_0x^0 + a_1x^1 + a_2x^2 + a_3x^3 + ...) = 1 (i=(1)ix23i2i)(a0x0+a1x1+a2x2+a3x3+...)=1

对比等式左右,就知道 a 0 = 1 a_0=1 a0=1,而后面的项如果递推求的话, i i i次方项我可以在 O ( i ) O(\sqrt i) O(i )时间内求出

若要求第 n n n项,则

最终的时间复杂度是
O ( ∑ i = 0 n i 1 2 ) = O ( ∫ 0 n x 1 2 ) = O ( n 3 2 ) O( \sum_{i=0}^n i^{\frac{1}{2}} ) = O( \int_0^{n} x^{\frac{1}{2}} ) = O( n^{\frac{3}{2}} ) O(i=0ni21)=O(0nx21)=O(n23)

代码

ll i, j;
cin >> n >> p;
a[0]=1;
rep(i,1,n)
{
    for(j=1;(3*j*j-j)/2<=i;j++)( j&1 ? a[i]+=a[i-(3*j*j-j)/2] : a[i]-=a[i-(3*j*j-j)/2] );
    for(j=-1;(3*j*j-j)/2<=i;j--)( j&1 ? a[i]+=a[i-(3*j*j-j)/2] : a[i]-=a[i-(3*j*j-j)/2] );
    a[i]=(a[i]%p+p)%p;
}
cout << a[n] << endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值