Files
contests/2023/rcpc/d1/editorial/D. Doping 2.cpp
2024-04-22 16:45:09 +03:00

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 << ' ';
}
}