考虑对每个x计算答案.
将除x以外的数都减去x,答案就是这些数的多重集(可以为空)和为0的方案数乘上(K+1), 最后加一个 k个 x
然而, t了6个点(别走Ψ( ̄∀ ̄)Ψ)
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e2 + 5, M = 1e6 + 5;
int n, m, _, k;
ll f1[M], f2[M];
int main() {
IOS; cin >> n >> k >> m;
VI ans; f1[0] = f2[0] = 1;
rep(i, 1, (n + 1) >> 1) {
int l = (i - 1) * i / 2 * k, r = (n - i + 1) * (n - i) / 2 * k;
rep(j, 1, l) f1[j] = 0;
rep(j, 1, r) f2[j] = 0;
rep(j, 1, i - 1) {
int r = (j - 1) * j / 2 * k, d = j * k;
rep(s, j, r) f1[s] = (f1[s] + f1[s - j]) % m;
per(s, r, d + j) f1[s] = (f1[s] + m - f1[s - d - j]) % m;
}
rep(j, 1, n - i) {
int r = (j - 1) * j / 2 * k, d = j * k;
rep(s, j, r) f2[s] = (f2[s] + f2[s - j]) % m;
per(s, r, d + j) f2[s] = (f2[s] + m - f2[s - d - j]) % m;
}
ll res = k;
per(s, min(l, r), 1) res = (res + f1[s] * f2[s] % m * (k + 1) % m) % m;
ans.pb(res);
}
for (auto i : ans) cout << i << '
';
per(i, ans.size() - 1 - (n & 1), 0) cout << ans[i] << '
';
return 0;
}
然而还可以优化, 思路是一样的, 直接把左右区间写成一个区间, 偏移量嘛
假定把 x 左边全部选上,也就是现在是最小值, 左区间全部-x(都是负数), 对于1~N(除了x), 选择 1~x-1, 相当于把最开始选择左区间的数扔掉了, ++a, 选择右区间, 也是 ++a是不是少了一个常数啊?
//对于 1e8小个常数是优化是相当高的
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e2 + 5, M = 1e6;
int n, m, _, k;
int a[M << 1], *f;
void add(int& x, int y){
x += y;
if(x >= m) x -= m;
}
void sub(int& x, int y){
x -= y;
if(x < 0) x += m;
}
int main() {
IOS; cin >> n >> k >> m;
VI ans; f = a + M;
rep(i, 1, (n + 1) >> 1) {
int l = -(i - 1) * i / 2 * k, r = (n - i + 1) * (n - i) / 2 * k;
rep(j, l, r) f[j] = 0; f[l] = 1; //左区间全选
VI res;
rep(j, 1, n) if (i != j) res.pb(abs(j - i)); //都是++a
sort(all(res)); r = l;
for (int x : res) {
int d = x * k; r += d;
rep(j, l + x, r) add(f[j], f[j - x]);
per(j, r, l + x + d) sub(f[j], f[j - d - x]);
}
ans.pb(((ll)f[0] * (k + 1) - 1 + m) % m);
}
rep(i, (n + 1 >> 1) + 1, n) ans.pb(ans[n - i]);
for (int i : ans) cout << i << '
';
return 0;
}