问存在多少个长度为
首先需要发现一个性质,就是如果
那这个东西有什么用呢,我们考虑对一波式子。首先我们需要去掉一个单调性,我们构造一个差分数组
这个下取整感觉很难受,我们就直接将
当
两边都加个
根据套路,我们需要把前面的
考虑我们将
其中
同样地,我们来考虑
补一补:
拆个
写成
不难发现当
综合奇偶两个式子,我们均可以得到:
其中
我们回到题目,除了这个条件,我们再回过头来看看有什么缺的条件,仔细找了找好像只有
于是我们考虑确定
我们发现只有两个条件:
于是满足条件的
我们令
我们最后要做的一件事情就是计算 dp 过去即可。
于是复杂度
cpp
#define _CRT_SECURE_NO_WARNINGS
#include <map>
#include <set>
#include <stack>
#include <ctime>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cctype>
#include <vector>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
inline char gc() {
static const int L = 233333;
static char sxd[L], *sss = sxd, *ttt = sxd;
if (sss == ttt) {
ttt = (sss = sxd) + fread(sxd, 1, L, stdin);
if (sss == ttt) {
return EOF;
}
}
return *sss++;
}
#ifndef _AT_HOME
#define dd c = gc()
#else
#define dd c = getchar()
#endif
inline char readalpha() {
char dd;
for (; !isalpha(c); dd);
return c;
}
inline char readchar() {
char dd;
for (; c == ' '; dd);
return c;
}
template <class T>
inline bool read(T& x) {
bool flg = false;
char dd;
x = 0;
for (; !isdigit(c); dd) {
if (c == '-') {
flg = true;
} else if(c == EOF) {
return false;
}
}
for (; isdigit(c); dd) {
x = (x * 10) + (c ^ 48);
}
if (flg) {
x = -x;
}
return true;
}
#undef dd
template <class T>
inline void write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x < 10) {
putchar(x | 48);
return;
}
write(x / 10);
putchar((x % 10) | 48);
}
template <class T>
inline void writesp(T x) {
write(x);
putchar(' ');
}
template <class T>
inline void writeln(T x) {
write(x);
puts("");
}
#define lowbit(x) (x & -x)
namespace dfcmd {
typedef long long LL;
const int maxn = 5005;
int n, mod;
int f[maxn];
int xs[maxn];
int Main() {
read(n), read(mod);
for (int i = 2, cntt = 1; i <= n; ++i, ++cntt) {
xs[i] = cntt;
}
for (int i = n, cntt = 2; i >= 2; --i, ++cntt) {
if (xs[i] <= cntt) {
break;
}
xs[i] = cntt;
}
f[0] = 1;
for (int i = 2; i <= n; ++i) {
for (int j = xs[i]; j < n; ++j) {
f[j] += f[j - xs[i]];
if (f[j] >= mod) {
f[j] -= mod;
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += (LL) (n - i) * f[i] % mod;
if (ans >= mod) {
ans -= mod;
}
}
writeln(ans);
return 0;
}
}
int main() {
return dfcmd::Main();
}