143 lines
2.5 KiB
C++
143 lines
2.5 KiB
C++
/// Cozma Tiberiu - Stefan
|
|
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
int mod;
|
|
const int nmax = 100;
|
|
struct Mint
|
|
{
|
|
int val;
|
|
Mint(int _val = 0)
|
|
{
|
|
val = _val % mod;
|
|
}
|
|
Mint(long long _val)
|
|
{
|
|
val = _val % mod;
|
|
}
|
|
Mint operator+(Mint oth)
|
|
{
|
|
return val + oth.val;
|
|
}
|
|
Mint operator*(Mint oth)
|
|
{
|
|
return 1LL * val * oth.val;
|
|
}
|
|
Mint operator-(Mint oth)
|
|
{
|
|
return val - oth.val + mod;
|
|
}
|
|
};
|
|
Mint dp[nmax+1][nmax+1][nmax+1];
|
|
Mint sum[nmax+1][nmax+1][nmax+1];
|
|
Mint dp2[nmax+1][nmax+1];
|
|
int main()
|
|
{
|
|
cin.tie(nullptr)->sync_with_stdio(false);
|
|
int n;
|
|
cin >> n >> mod;
|
|
vector<int> a(n + 1);
|
|
for (int i = 1; i <= n; ++i)
|
|
{
|
|
cin >> a[i];
|
|
}
|
|
dp[1][1][0] = 1;
|
|
sum[1][1][0] = 1;
|
|
for (int i = 2; i <= n; ++i)
|
|
{
|
|
for (int j = 1; j <= i; ++j)
|
|
{
|
|
for (int k = 0; k < i; ++k)
|
|
{
|
|
dp[i][j][k] = sum[i - 1][i - 1][k] - sum[i - 1][j - 1][k];
|
|
if (k)
|
|
{
|
|
dp[i][j][k] = dp[i][j][k] + sum[i - 1][j - 1][k - 1];
|
|
}
|
|
sum[i][j][k] = sum[i][j - 1][k] + dp[i][j][k];
|
|
}
|
|
}
|
|
}
|
|
vector<vector<Mint>> pas(n + 1, vector<Mint>(n + 1));
|
|
pas[0][0] = 1;
|
|
for (int i = 1; i <= n; ++i)
|
|
{
|
|
for (int j = 0; j <= i; ++j)
|
|
{
|
|
if (j == 0 || j == i)
|
|
{
|
|
pas[i][j] = 1;
|
|
continue;
|
|
}
|
|
pas[i][j] = pas[i - 1][j] + pas[i - 1][j - 1];
|
|
}
|
|
}
|
|
set<int> vals;
|
|
for (int i = 1; i <= n; ++i)
|
|
{
|
|
vals.insert(i);
|
|
}
|
|
int cnt = 0;
|
|
vector<Mint> ans(n + 1);
|
|
for (int i = 1; i <= n; ++i)
|
|
{
|
|
for (int j = 1; j < a[i]; ++j)
|
|
{
|
|
if (vals.find(j) != vals.end())
|
|
{
|
|
vals.erase(j);
|
|
cnt += vals.find(j + 1) != vals.end();
|
|
vector<int> left(1);
|
|
for (auto k : vals)
|
|
{
|
|
left.push_back(k);
|
|
}
|
|
int sz = 1;
|
|
vector<int> lg(1);
|
|
for (int i = 2; i < (int)left.size(); ++i)
|
|
{
|
|
if (left[i] == left[i - 1] + 1)
|
|
{
|
|
sz++;
|
|
}
|
|
else
|
|
{
|
|
lg.push_back(sz);
|
|
sz = 1;
|
|
}
|
|
}
|
|
lg.push_back(sz);
|
|
int m = (int)lg.size() - 1;
|
|
dp2[0][0] = 1;
|
|
int s = 0;
|
|
for (int x = 1; x <= m; ++x)
|
|
{
|
|
s += lg[x];
|
|
for (int y = 0; y < n; ++y)
|
|
{
|
|
dp2[x][y].val = 0;
|
|
for (int z = 0; z <= min(y, lg[x]); ++z)
|
|
{
|
|
dp2[x][y] = dp2[x][y] + dp2[x - 1][y - z] * pas[s][lg[x]] * sum[lg[x]][lg[x]][z];
|
|
}
|
|
}
|
|
}
|
|
for (int k = 0; k < n; ++k)
|
|
{
|
|
int need = k - cnt;
|
|
if (need >= 0)
|
|
{
|
|
ans[k] = ans[k] + dp2[m][need];
|
|
}
|
|
}
|
|
vals.insert(j);
|
|
cnt -= vals.find(j + 1) != vals.end();
|
|
}
|
|
}
|
|
vals.erase(a[i]);
|
|
cnt += vals.find(a[i] + 1) != vals.end();
|
|
}
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
cout << ans[i].val << ' ';
|
|
}
|
|
} |