洛谷P9035 Pont des souvenirs 题解

求有多少个长度为 n 的序列 a 满足如下所有约束:

  • 1a1a2...ank

  • ij,ai+ajk+1

答案对 109+7 取余。

70pts 做法

首先考虑到 an1an 两项是整个数列 a 中的最大的两项,所以若 an1+an 不超过 k+1,则数列中任意两项之和肯定不超过 k+1

考虑当 an1=x 时,首先可以计算出 an 的取值范围:

  • 因为 an1an,故 anx

  • 因为 an1+ank+1,则 ank+1x

所以 xank+1x,取值数量为 k+22x,当 x>k+1x 时取值数量为 0

考虑第一个约束,因为:

1a1a2...an2an1

将不等式的每一个部分加上下标,为了方便,下式的表达式所加的下标从 0 开始:

1a1+0<a2+1<...<an2+n3<x+n2

所以 an2+n3x+n3

具体证明本蒟蒻不太会,建议查询相关资料。

于是我们可以得到 a 数列的前 n2 项就是在 [1,x+n3] 范围中选择 n2 个数,方案数为 (x+n3n2)

于是对于 an1=x,方案数为 (x+n3n2)×max(k+22x,0)

累加所有的可能,答案为:

i=1k+1(i+n3n2)×max(k+22i,0)

100pts 做法

我们只需要化简如上求和式子即可,本蒟蒻不会等号对齐,故观感可能较差。

首先 max(k+22i,0) 很难化简,于是我们需要求出 i 的上界,解不等式可得 k+12,为了之后化简的方便,以下用 m+1 代替该数字。

i=1k+1(i+n3n2)×max(k+22i,0)

化为:

i=1m+1(i+n3n2)×(k2i)

运用乘法分配律得:

k×i=0m(i+n2n2)2×i=0m(i+n2n2)×i

由组合数公式,得:

k×(m+n1n1)2×i=0m(i+n2n2)×i

由于 ×0 无意义,故省去,得:

k×(m+n1n1)2×i=1m(i+n2n2)×i

变换形式,得:

k×(m+n1n1)2×i=1mj=1i(i+n2n2)

调换求和顺序,得:

k×(m+n1n1)2×j=1mi=jm(i+n2n2)

将第二个求和换成两式相减,得:

k×(m+n1n1)2×j=1m(i=0m(i+n2n2)i=0j1(i+n2n2))

运用组合数公式,得:

k×(m+n1n1)2×j=1m((m+n1n1)(j1+n1n1))

拆除一个括号,方便化简,得:

k×(m+n1n1)2×j=1m(m+n1n1)+2×j=1m(j1+n1n1)

化简第一个求和,得:

k×(m+n1n1)2m×(m+n1n1)+2×j=1m(j1+n1n1)

降低求和范围,得:

(k2m)×(m+n1n1)+2×j=0m1(j+n1n1)

运用组合数公式,得:

(k2m)×(m+n1n1)+2×(m+n1n)

至此,我们就化简完毕,可以预处理阶乘及其逆元,求组合数时 O(1) 求解。

posted @   ydzr00000  阅读(59)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示