QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#673289#9444. Again Permutation ProblemwangjunruiTL 0ms3668kbC++142.2kb2024-10-24 21:35:312024-10-24 21:35:31

Judging History

This is the latest submission verdict.

  • [2024-10-24 21:35:31]
  • Judged
  • Verdict: TL
  • Time: 0ms
  • Memory: 3668kb
  • [2024-10-24 21:35:31]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N = 31;
constexpr int mod = 998244353;
template <typename T>
inline void add(T &x, T y)
{
	x += y;
	if (x >= mod)
		x -= mod;
}
int n, m;
int rcnt[N];
vector<int> r[N][N], invr[N][N];
vector<vector<int>> t[N];
inline vector<int> operator * (const vector<int> &lhs, const vector<int> &rhs)
{
	vector<int> res(n);
	for (int i = 0; i < n; ++i)
		res[i] = lhs[rhs[i]];
	return res;
}
inline void dfs(int u, const vector<int> &);
inline void init()
{
	for (int i = 0; i < n; ++i)
	{
		++rcnt[i];
		r[i][i].resize(n), invr[i][i].resize(n);
		for (int j = i; j < n; ++j)
			r[i][i][j] = invr[i][i][j] = j;
	}
}
inline bool contain(int u, const vector<int> &g)
{
	if (u == n)
		return true;
	int v = g[u];
	if (r[u][v].empty())
		return false;
	return contain(u + 1, g * invr[u][v]);
}
inline void add(int u, const vector<int> &g)
{
	if (contain(u, g))
		return;
	t[u].push_back(g);
	vector<int> h(n);
	for (int v = u; v < n; ++v)
		if (!r[u][v].empty())
			dfs(u, r[u][v] * g);
}
inline void dfs(int u, const vector<int> &g)
{
	int v = g[u];
	if (!r[u][v].empty())
		add(u + 1, invr[u][v] * g);
	else
	{
		++rcnt[u];
		r[u][v].resize(n), invr[u][v].resize(n);
		for (int w = u; w < n; ++w)
			invr[u][v][r[u][v][w] = g[w]] = w;
		for (auto f : t[u])
			dfs(u, f * g);
	}
}
int dp[N][N][N];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	init();
	for (int i = 0; i < m; ++i)
	{
		vector<int> p(n);
		for (int j = 0; j < n; ++j)
		{
			cin >> p[j];
			--p[j];
		}
		add(0, p);
	}
	for (int x = 0; x < n; ++x)
		for (int y = x + 1; y < n; ++y)
			dp[n][x][y] = 1;
	for (int u = n - 1; u >= 0; --u)
		for (int v = 0; v < n; ++v)
		{
			if (r[u][v].empty())
				continue;
			for (int x = 0; x < n; ++x)
				for (int y = 0; y < n; ++y)
				{
					int nx = (x < u) ? x : r[u][v][x];
					int ny = (y < u) ? y : r[u][v][y];
					add(dp[u][nx][ny], dp[u + 1][x][y]);
				}
		}
	int res = 0;
	for (int x = 0; x < n; ++x)
		for (int y = 0; y < x; ++y)
			add(res, dp[0][x][y]);
	cout << res << '\n';
	return 0;
} 

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3668kb

input:

3 2
1 2 3
2 3 1

output:

4

result:

ok 1 number(s): "4"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3588kb

input:

5 2
3 4 5 1 2
1 5 4 3 2

output:

50

result:

ok 1 number(s): "50"

Test #3:

score: -100
Time Limit Exceeded

input:

30 12
1 2 9 4 5 6 7 8 3 10 11 12 19 14 15 25 17 18 20 26 21 22 23 24 16 29 27 28 13 30
9 2 27 4 5 10 7 8 1 25 11 12 24 14 15 16 17 18 19 20 21 22 23 28 6 26 3 13 29 30
1 5 3 29 2 6 7 8 9 10 11 12 13 16 15 18 17 14 19 20 21 22 28 27 25 26 24 23 4 30
7 2 3 25 5 6 1 28 21 15 11 12 13 14 10 17 16 18 19 ...

output:


result: