[Leaf] [ARC215D] cresc.

d---cresc.">D - cresc.

1. 题面梗概

中译中:构造一个长度为 NN 的非降序列 SS,要求存在一个长度为 N+1N+1 的辅助序列 AA(元素均在 [0,M][0, M] 之间),满足相邻项之和等于 SS 的项。求满足条件的 SS 的数量。

Si=Ai+Ai+1S_i = A_i + A_{i+1}.
1≤N,M≤1071 \le N, M \le 10^7, 结果对 109+710^9 + 7 取模。

2. 逻辑推导

这显然是个 组合数学 推导题,在没有别的性质前,我们先从 SS 的定义出发分析。

2.1 奇偶分组

因为 SS 是非降的,我们试试差分能不能发现什么规律。

Di=Si+1−Si=(Ai+1+Ai+2)−(Ai+Ai+1)=Ai+2−Ai≥0D_{i} = S_{i+1} - S_{i} = (A_{i+1} + A_{i+2}) - (A_{i} + A_{i+1}) = A_{i+2} - A_{i} \geq 0

这意味着序列 AA 在 奇数下标 和 偶数下标 上分别是 非降 的。

  • 奇数:A1→d1A3→d3A5…A_1 \xrightarrow{d_1} A_3 \xrightarrow{d_3} A_5 \dots

  • 偶数:A2→d2A4→d4A6…A_2 \xrightarrow{d_2} A_4 \xrightarrow{d_4} A_6 \dots

2.2 约束

因为 S1=A1+A2S_{1} = A_{1} + A_{2},那么只需要知道 SS 和剩下 N−1N - 1 个 差分变量 DiD_{i} 就可以构造出整个数列 SS 了。

  • 奇数:共有 kx=⌊N2⌋k_{x} = \left\lfloor \frac{N}{2} \right\rfloor 个变量(即 d1,d3,…d_{1}, d_{3}, \dots ),设它们总和为 XX。

  • 偶数:共有 ky=⌊N−12⌋k_{y} = \left\lfloor \frac{N-1}{2} \right\rfloor 个变量(即 d2,d4,…d_{2}, d_{4}, \dots ),设它们总和为 YY。

为了保证 AA 的所有元素都在 [0,M][0, M],我们分析奇偶数:

  • 奇数:0≤A1≤Akx=A1+X≤M0 \leq A_{1} \leq A_{k_{x}} = A_{1} + X \leq M,也就是 X≤MX \leq M。
  • 偶数:A2+Y≤MA_{2} + Y \leq M,同理 Y≤MY \leq M。
  • 同时因为 A1+A2=S1A_{1} + A_{2} = S_{1},所以 S1+X+Y≤2MS_{1} + X + Y \leq 2M。

2.3 计数

现在问题就转化为了,有多少组非负整数解满足上述三个约束条件。

发现这个不等式 S1+X+Y≤2MS_{1} + X + Y \leq 2M 有点麻烦,我们把它变成等式:

S1+X+Y+W=2MS_{1} + X + Y + W = 2M

一共有 1+kx+ky+1=1+(N−1)+1=N+11 + k_{x} + k_{y} + 1 = 1 + (N - 1) + 1 = N + 1 个变量。

那么把 2M2M 分给 N+1N + 1 个变量,根据隔板法公式:

Total=(2M+NN)Total = \binom{2M + N}{N}

2.4 容斥

由于总数只有 2M2M,而条件是 X≤MX \leq M 且 Y≤MY \leq M,所以要么 kxk_{x} 多了,要么 kyk_{y} 多了。

因为 X+Y≤2MX + Y \leq 2M,所以它们不可能同时多拿。

假设 kxk_{x} 拿多了的情况,剩下来的 统称为 ZZ,共 m=N+1−kxm = N + 1 - k_{x} 个。

我们枚举 XX 拿了 jj 个的情况。( M+1≤j≤2MM + 1 \leq j \leq 2M )

S(kx,m)=∑j=M+12M[(j+(kx−1)(kx−1))×((2M−j)+(m−1)m−1)]S(k_{x}, m) = \sum_{j=M+1}^{2M} \left[ \binom{j + (k_{x} - 1)}{(k_{x} - 1)} \times \binom{(2M - j) + (m - 1)}{m - 1} \right]

XX 组:kxk_{x} 分 jj;ZZ 组:mm 分 2M−j2M - j。

而 kyk_{y} 多拿的情况对称,只需要把 kxk_{x} 换成 kyk_{y} 即可。

3. 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int maxn = 3e7 + 5;
const int mod = 1e9 + 7;

ll N, M;

ll fac[maxn], inv[maxn];

ll qpow( ll a, ll b )
{
ll res = 1;
while( b )
{
if( b & 1 ) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}

ll C( ll n, ll k )
{
if( n < k ) return 0;
return ( fac[n] * inv[k] % mod ) * inv[n - k] % mod;
}

void init( )
{
fac[0] = inv[0] = 1;
for( int i = 1; i < maxn; ++ i ) fac[i] = ( fac[i - 1] * i ) % mod;
inv[maxn - 1] = qpow( fac[maxn - 1], mod - 2 );
for( int i = maxn - 2; i >= 1; -- i ) inv[i] = ( inv[i + 1] * (i + 1) ) % mod;
}

ll calc( ll x, ll y )
{
ll res = 0;
for( int i = M + 1; i <= 2 * M; ++ i )
{
ll t1 = C( i + (x - 1), (x - 1) );
ll t2 = C( (2 * M - i) + (y + 1), (y + 1) );
res = ( res + t1 * t2 ) % mod;
}
return res;
}

void solve( )
{
cin >> N >> M;

int cnt1 = N / 2, cnt2 = ( N + 1 ) / 2 - 1;

ll ans = C( 2 * M + N, N );

ans = ( ans - calc( cnt1, cnt2 ) + mod ) % mod;
ans = ( ans - calc( cnt2, cnt1 ) + mod ) % mod;

cout << ans << '\n';
}

int main( )
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
init( );
solve( );
return 0;
}

4. 复盘

  • 复杂度分析:O(N+M)O(N + M) 。

  • 认知补丁:

    • 差分变量的起源:想明白 di=Ai+2−Aid_i = A_{i+2} - A_i 这一步是解题的关键,它将序列 SS 唯一映射到了两根独立的 AA 序列锁链的增长步长上。

    • 垃圾桶变量 (WW):它是解开不等式的钥匙。它让我们能够把“分苹果”从“不知道剩下多少”的模糊状态,转化成“一定分完 2M 个”的确定等式。

  • 碎碎念:先通过单调性差分(类似求导),然后再通过组合数学结合容斥原理求解出答案,

  • 关联笔记:[[组合计数]]


[Leaf] [ARC215D] cresc.
http://miqiu.space/posts/cba0509f/
作者
Miqiu
发布于
2026年2月24日
许可协议