观察这个数列:[1,3,0,2,1,1,2][1, 3, 0, 2, -1,1, -2 \cdots]

这个数列中后一项总是比前一项增加 22 或者减少 33且每一项都为整数

栋栋对这种数列很好奇,他想知道长度为 nn 和为 ss 而且后一项总是比前一项增加 aa 或者减少 bb 的整数数列可能有多少种呢?

输入格式

共一行,包含四个整数 n,s,a,bn,s,a,b,含义如前面所述。

输出格式

共一行,包含一个整数,表示满足条件的方案数。

由于这个数很大,请输出方案数除以 100000007100000007 的余数。

数据范围

1n10001≤n≤1000,
109s109−10^9≤s≤10^9,
1a,b1061≤a,b≤10^6.

输入样例:

1
4 10 2 3

输出样例:

1
2

样例解释

两个满足条件的数列分别是 [2,4,1,3][2,4,1,3][7,4,1,2][7,4,1,-2]

思路

设数列的第一个数为 xx,则整个数列为 x,x+d1,x+d1+d2,,x+i=1n1dix,x+d_1,x+d_1+d_2,\cdots,x+\sum\limits_{i=1}^{n-1}d_i,其中 di=ad_i=adi=bd_i=-b。按照题意,要求 s=i=1n(x+j=1i1dj)s=\sum\limits_{i=1}^n\left(x+\sum\limits_{j=1}^{i-1}d_j\right),即 s=nx+i=1n1(ni)dis=nx+\sum\limits_{i=1}^{n-1}(n-i)d_i;由于 xx 是任意取的,我们可以在模意义下将其消去,即 si=1n1(ni)di(modn)s\equiv \sum\limits_{i=1}^{n-1}(n-i)d_i\pmod n

问题转化成,有一个 n1n-1 长度的数列,数列中元素的值只可以取 aab-b,数列元素满足 si=1n1(ni)di(modn)s\equiv\sum\limits_{i=1}^{n-1}(n-i)d_i\pmod n,问方案数。

f(i,j)f(i,j) 表示安排完前 ii 个元素,k=1i(nk)dkj(modn)\sum\limits_{k=1}^{i}(n-k)d_k\equiv j\pmod n 的方案数,考虑第 i+1i+1 个元素是什么:若安排 aa,则状态转移到 f(i+1,[j+(ni1)×a]modn)f(i+1,[j+(n-i-1)\times a]\bmod n);若安排 bb,则状态转移到 f(i+1,[j(ni1)×b]modn)f(i+1,[j-(n-i-1)\times b]\bmod n)

答案为 f(n1,smodn)f(n-1,s\bmod n)

代码

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
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: AcWing 1214
Date: 2021 Apr. 5th
Description: Dynamic Programming, Number Theory
*******************************************************************/
#include<iostream>
using namespace std;
typedef long long ll;
const ll MOD = 100000007;
const int MAX_N = 1004;
ll n;
ll s, a, b;
ll f[MAX_N][MAX_N];
ll mod(ll x) {
return (x % n + n) % n;
}
int main() {
cin >> n >> s >> a >> b;
f[0][0] = 1;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n; j++) {
f[i + 1][mod(j + (n - i - 1) * a)] += f[i][j];
f[i + 1][mod(j + (n - i - 1) * a)] %= MOD;
f[i + 1][mod(j - (n - i - 1) * b)] += f[i][j];
f[i + 1][mod(j - (n - i - 1) * b)] %= MOD;
}
}
cout << f[n - 1][mod(s)] << endl;
return 0;
}

后记

模数是 108+710^8+7,太窒息了!!!!