結果

問題 No.1428 PeRmutation Question
ユーザー ecotteaecottea
提出日時 2023-07-27 18:31:31
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 24,308 bytes
コンパイル時間 5,735 ms
コンパイル使用メモリ 295,324 KB
実行使用メモリ 5,248 KB
最終ジャッジ日時 2024-10-04 17:56:59
合計ジャッジ時間 6,109 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 1 ms
5,248 KB
testcase_07 WA -
testcase_08 AC 2 ms
5,248 KB
testcase_09 AC 2 ms
5,248 KB
testcase_10 WA -
testcase_11 AC 2 ms
5,248 KB
testcase_12 AC 3 ms
5,248 KB
testcase_13 AC 10 ms
5,248 KB
testcase_14 AC 8 ms
5,248 KB
testcase_15 AC 7 ms
5,248 KB
testcase_16 AC 12 ms
5,248 KB
testcase_17 AC 12 ms
5,248 KB
testcase_18 AC 6 ms
5,248 KB
testcase_19 AC 5 ms
5,248 KB
testcase_20 AC 4 ms
5,248 KB
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 AC 12 ms
5,248 KB
testcase_31 WA -
testcase_32 AC 11 ms
5,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#ifndef HIDDEN_IN_VS // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; // -2^63 ~ 2^63 = 9 * 10^18(int は -2^31 ~ 2^31 = 2 * 10^9)
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;	using vvvvi = vector<vvvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;	using vvvvl = vector<vvvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = acos(-1);
const vi DX = { 1, 0, -1, 0 }; // 4 近傍(下,右,上,左)
const vi DY = { 0, 1, 0, -1 };
int INF = 1001001001; ll INFL = 4004004003104004004LL; // (int)INFL = 1010931620;
double EPS = 1e-15;

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), x))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), x))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素(変更不可能)
#define repea(v, a) for(auto& v : (a)) // a の全要素(変更可能)
#define repb(set, d) for(int set = 0; set < (1 << int(d)); ++set) // d ビット全探索(昇順)
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て(昇順)
#define smod(n, m) ((((n) % (m)) + (m)) % (m)) // 非負mod
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
#define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定

// 汎用関数の定義
template <class T> inline ll pow(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新(更新されたら true を返す)
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新(更新されたら true を返す)
template <class T> inline T get(T set, int i) { return (set >> i) & T(1); }

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }

#endif // 折りたたみ用


#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;

#ifdef _MSC_VER
#include "localACL.hpp"
#endif

using mint = modint1000000007;
//using mint = modint998244353;
//using mint = modint; // mint::set_mod(m);

namespace atcoder {
	inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
	inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>;
#endif


#ifdef _MSC_VER // 手元環境(Visual Studio)
#include "local.hpp"
#else // 提出用(gcc)
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : -1; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : -1; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define gcd __gcd
#define dump(...)
#define dumpel(v)
#define dump_list(v)
#define dump_mat(v)
#define input_from_file(f)
#define output_to_file(f)
#define Assert(b) { if (!(b)) while (1) cout << "OLE"; }
#endif


//【階乗など(法が大きな素数)】
/*
* Factorial_mint(int N) : O(n)
*	N まで計算可能として初期化する.
*
* mint fact(int n) : O(1)
*	n! を返す.
*
* mint fact_inv(int n) : O(1)
*	1/n! を返す(n が負なら 0 を返す)
*
* mint inv(int n) : O(1)
*	1/n を返す.
*
* mint perm(int n, int r) : O(1)
*	順列の数 nPr を返す.
*
* mint bin(int n, int r) : O(1)
*	二項係数 nCr を返す.
*
* mint mul(vi rs) : O(|rs|)
*	多項係数 nC[rs] を返す.(n = Σrs)
*/
class Factorial_mint {
	int n_max;

	// 階乗と階乗の逆数の値を保持するテーブル
	vm fac, fac_inv;

public:
	// n! までの階乗とその逆数を前計算しておく.O(n)
	Factorial_mint(int n) : n_max(n), fac(n + 1), fac_inv(n + 1) {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		fac[0] = 1;
		repi(i, 1, n) fac[i] = fac[i - 1] * i;

		fac_inv[n] = fac[n].inv();
		repir(i, n - 1, 0) fac_inv[i] = fac_inv[i + 1] * (i + 1);
	}
	Factorial_mint() : n_max(0) {} // ダミー

	// n! を返す.
	mint fact(int n) const {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		Assert(0 <= n && n <= n_max);
		return fac[n];
	}

	// 1/n! を返す(n が負なら 0 を返す)
	mint fact_inv(int n) const {
		// verify : https://atcoder.jp/contests/abc289/tasks/abc289_h

		Assert(n <= n_max);
		if (n < 0) return 0;
		return fac_inv[n];
	}

	// 1/n を返す.
	mint inv(int n) const {
		// verify : https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d

		Assert(0 < n && n <= n_max);
		return fac[n - 1] * fac_inv[n];
	}

	// 順列の数 nPr を返す.
	mint perm(int n, int r) const {
		// verify : https://atcoder.jp/contests/abc172/tasks/abc172_e

		Assert(n <= n_max);

		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[n - r];
	}

	// 二項係数 nCr を返す.
	mint bin(int n, int r) const {
		// verify : https://atcoder.jp/contests/abc034/tasks/abc034_c

		Assert(n <= n_max);
		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[r] * fac_inv[n - r];
	}

	// 多項係数 nC[rs] を返す.
	mint mul(const vi& rs) const {
		// verify : https://yukicoder.me/problems/no/2141

		if (*min_element(all(rs)) < 0) return 0;
		int n = accumulate(all(rs), 0);
		Assert(n <= n_max);

		mint res = fac[n];
		repe(r, rs) res *= fac_inv[r];

		return res;
	}
};


//【置換の合成 群】(参照渡ししていないので遅い)
/*
* S ∋ f[0..n) : 置換 i → f[i] を表す.
* f op g : 合成置換 f o g を返す.
*/
// verify : https://yukicoder.me/problems/no/2384
using S606 = vi;
S606 op606(S606 a, S606 b) {
	if (sz(a) == 0) return b;
	if (sz(b) == 0) return a;

	int n = sz(a);
	S606 res(n);
	rep(i, n) res[i] = a[b[i]];

	return res;
}
S606 e606() { return S606(); }
S606 inv606(S606 a) {
	if (sz(a) == 0) return a;

	int n = sz(a);
	S606 res(n);
	rep(i, n) res[a[i]] = i;

	return res;
}
#define PermutationComposite_group S606, op606, e606, inv606


//【転倒数】O(n log n)
/*
* a[0..n) の転倒数を返す.
*/
template <class T>
ll inversion_number(const vector<T>& a) {
	// verify : https://atcoder.jp/contests/arc075/tasks/arc075_c

	int n = sz(a);

	// 値 a[i] と位置 i を組にしソートする.
	vector<pair<T, int>> ai(n);
	rep(i, n) ai[i] = { a[i], i };
	sort(all(ai));

	ll res = 0;

	// ft[i] : いままでに位置 i の要素が現れたか
	fenwick_tree<int> ft(n);

	// 値について昇順に見ていく.
	rep(j, n) {
		// pos : 昇順で j 番目の値の位置
		int pos = ai[j].second;

		// pos より右に j 未満の要素が今までに何個あったかを加算する.
		res += ft.sum(pos + 1, n);

		// 位置 pos の要素の出現を記録する.
		ft.add(pos, 1);
	}

	return res;
}


//【置換のサイクル分解】O(n)
/*
* [0..n) の置換 p を巡回置換の積に分解して cycles に格納し cycles を返す.
* p は任意の i を p[i] に動かすような置換を表す.
*/
vvi permutation_decomposition(const vi& p) {
	// verify : https://atcoder.jp/contests/abc175/tasks/abc175_d

	int n = sz(p);

	vvi cycles;
	vb seen(n);

	rep(i, n) {
		// 抽出済のサイクルに含まれるなら次へ
		if (seen[i]) continue;

		// 新しいサイクルを発見
		cycles.push_back(vi());

		// サイクルを順に格納していく.
		int s = i;
		do {
			cycles.rbegin()->push_back(s);
			seen[s] = true;
			s = p[s];
		} while (s != i);
	}

	return cycles;
}


void zikken() {
	int n = 8;

	set<vi> s; vvi a;

	vi p(n);
	iota(all(p), 0);

	repp(p) {
		if (inversion_number(p) % 2 == 0) a.push_back(p);
		s.insert(p);
	}

	vvvi orbits;

	while (!s.empty()) {
		auto s0 = *s.begin();

		vvi orbit;
		repe(p, a) orbit.push_back(op606(op606(inv606(p), s0), p));
		uniq(orbit);

		repe(p, orbit) s.erase(p);
		orbits.push_back(orbit);
	}

	repe(orbit, orbits) {
		auto cycles = permutation_decomposition(orbit[0]);
		rep(i, sz(cycles)) cout << sz(cycles[i]) << ",:"[i == sz(cycles) - 1];

		repe(p, orbit) {
			auto cycles = permutation_decomposition(p);
			cout << " ";
			repe(cycle, cycles) {
				cout << "(";
				repe(x, cycle) cout << x;
				cout << ")";
			}
			break; // 出力量の抑制
		}
		cout << endl;
	}

	exit(0);
}
/*
n = 1
1: (0)
S_1 の共役類と同じ.

n = 2
1,1: (0)(1)
2: (01)
S_2 の共役類と同じ.

n = 3
1,1,1: (0)(1)(2)
1,2: (0)(12) (01)(2) (02)(1)
3: (012)
3: (021)
大体 S_3 の共役類と同じだが,長さ 3 の巡回置換だけ 2 つの軌道に分かれている.

n = 4
1,1,1,1: (0)(1)(2)(3)
1,1,2: (0)(1)(23) (0)(12)(3) (0)(13)(2) (01)(2)(3) (02)(1)(3) (03)(1)(2)
1,3: (0)(123) (013)(2) (021)(3) (032)(1)
1,3: (0)(132) (012)(3) (023)(1) (031)(2)
2,2: (01)(23) (02)(13) (03)(12)
4: (0123) (0132) (0231) (0213) (0321) (0312)
大体 S_4 の共役類と同じだが,長さ 3 の巡回置換だけ 2 つの軌道に分かれている.

n = 5
1,1,1,1,1: (0)(1)(2)(3)(4)
1,1,1,2: (0)(1)(2)(34) (0)(1)(23)(4) (0)(1)(24)(3) (0)(12)(3)(4) (0)(13)(2)(4) (0)(14)(2)(3) (01)(2)(3)(4) (02)(1)(3)(4) (03)(1)(2)(4) (04)(1)(2)(3)
1,1,3: (0)(1)(234) (0)(1)(243) (0)(123)(4) (0)(124)(3) (0)(132)(4) (0)(134)(2) (0)(142)(3) (0)(143)(2) (012)(3)(4) (013)(2)(4) (014)(2)(3) (021)(3)(4) (023)(1)(4) (024)(1)(3) (031)(2)(4) (032)(1)(4) (034)(1)(2) (041)(2)(3) (042)(1)(3) (043)(1)(2)
1,2,2: (0)(12)(34) (0)(13)(24) (0)(14)(23) (01)(2)(34) (01)(23)(4) (01)(24)(3) (02)(1)(34) (02)(13)(4) (02)(14)(3) (03)(1)(24) (03)(12)(4) (03)(14)(2) (04)(1)(23) (04)(12)(3) (04)(13)(2)
1,4: (0)(1234) (0)(1243) (0)(1342) (0)(1324) (0)(1432) (0)(1423) (0123)(4) (0124)(3) (0132)(4) (0134)(2) (0142)(3) (0143)(2) (0231)(4) (0241)(3) (0234)(1) (0243)(1) (0213)(4) (0214)(3) (0321)(4) (0341)(2) (0342)(1) (0324)(1) (0312)(4) (0314)(2) (0421)(3) (0431)(2) (0432)(1) (0423)(1) (0412)(3) (0413)(2)
2,3: (01)(234) (01)(243) (012)(34) (013)(24) (014)(23) (021)(34) (02)(134) (024)(13) (02)(143) (023)(14) (031)(24) (034)(12) (03)(124) (032)(14) (03)(142) (041)(23) (043)(12) (04)(123) (042)(13) (04)(132)
5: (01234) (01342) (01423) (02431) (02143) (02314) (03241) (03412) (03124) (04321) (04132) (04213)
5: (01243) (01324) (01432) (02341) (02134) (02413) (03421) (03142) (03214) (04231) (04312) (04123)
大体 S_5 の共役類と同じだが,長さ 5 の巡回置換だけ 2 つの軌道に分かれている.

n = 6
1,1,1,1,1,1: (0)(1)(2)(3)(4)(5)
1,1,1,1,2: (0)(1)(2)(3)(45) (0)(1)(2)(34)(5) (0)(1)(2)(35)(4) (0)(1)(23)(4)(5) (0)(1)(24)(3)(5) (0)(1)(25)(3)(4) (0)(12)(3)(4)(5) (0)(13)(2)(4)(5) (0)(14)(2)(3)(5) (0)(15)(2)(3)(4) (01)(2)(3)(4)(5) (02)(1)(3)(4)(5) (03)(1)(2)(4)(5) (04)(1)(2)(3)(5) (05)(1)(2)(3)(4)
1,1,1,3: (0)(1)(2)(345) (0)(1)(2)(354) (0)(1)(234)(5) (0)(1)(235)(4) (0)(1)(243)(5) (0)(1)(245)(3) (0)(1)(253)(4) (0)(1)(254)(3) (0)(123)(4)(5) (0)(124)(3)(5) (0)(125)(3)(4) (0)(132)(4)(5) (0)(134)(2)(5) (0)(135)(2)(4) (0)(142)(3)(5) (0)(143)(2)(5) (0)(145)(2)(3) (0)(152)(3)(4) (0)(153)(2)(4) (0)(154)(2)(3) (012)(3)(4)(5) (013)(2)(4)(5) (014)(2)(3)(5) (015)(2)(3)(4) (021)(3)(4)(5) (023)(1)(4)(5) (024)(1)(3)(5) (025)(1)(3)(4) (031)(2)(4)(5) (032)(1)(4)(5) (034)(1)(2)(5) (035)(1)(2)(4) (041)(2)(3)(5) (042)(1)(3)(5) (043)(1)(2)(5) (045)(1)(2)(3) (051)(2)(3)(4) (052)(1)(3)(4) (053)(1)(2)(4) (054)(1)(2)(3)
1,1,2,2: (0)(1)(23)(45) (0)(1)(24)(35) (0)(1)(25)(34) (0)(12)(3)(45) (0)(12)(34)(5) (0)(12)(35)(4) (0)(13)(2)(45) (0)(13)(24)(5) (0)(13)(25)(4) (0)(14)(2)(35) (0)(14)(23)(5) (0)(14)(25)(3) (0)(15)(2)(34) (0)(15)(23)(4) (0)(15)(24)(3) (01)(2)(3)(45) (01)(2)(34)(5) (01)(2)(35)(4) (01)(23)(4)(5) (01)(24)(3)(5) (01)(25)(3)(4) (02)(1)(3)(45) (02)(1)(34)(5) (02)(1)(35)(4) (02)(13)(4)(5) (02)(14)(3)(5) (02)(15)(3)(4) (03)(1)(2)(45) (03)(1)(24)(5) (03)(1)(25)(4) (03)(12)(4)(5) (03)(14)(2)(5) (03)(15)(2)(4) (04)(1)(2)(35) (04)(1)(23)(5) (04)(1)(25)(3) (04)(12)(3)(5) (04)(13)(2)(5) (04)(15)(2)(3) (05)(1)(2)(34) (05)(1)(23)(4) (05)(1)(24)(3) (05)(12)(3)(4) (05)(13)(2)(4) (05)(14)(2)(3)
1,1,4: (0)(1)(2345) (0)(1)(2354) (0)(1)(2453) (0)(1)(2435) (0)(1)(2543) (0)(1)(2534) (0)(1234)(5) (0)(1235)(4) (0)(1243)(5) (0)(1245)(3) (0)(1253)(4) (0)(1254)(3) (0)(1342)(5) (0)(1352)(4) (0)(1345)(2) (0)(1354)(2) (0)(1324)(5) (0)(1325)(4) (0)(1432)(5) (0)(1452)(3) (0)(1453)(2) (0)(1435)(2) (0)(1423)(5) (0)(1425)(3) (0)(1532)(4) (0)(1542)(3) (0)(1543)(2) (0)(1534)(2) (0)(1523)(4) (0)(1524)(3) (0123)(4)(5) (0124)(3)(5) (0125)(3)(4) (0132)(4)(5) (0134)(2)(5) (0135)(2)(4) (0142)(3)(5) (0143)(2)(5) (0145)(2)(3) (0152)(3)(4) (0153)(2)(4) (0154)(2)(3) (0231)(4)(5) (0241)(3)(5) (0251)(3)(4) (0234)(1)(5) (0235)(1)(4) (0243)(1)(5) (0245)(1)(3) (0253)(1)(4) (0254)(1)(3) (0213)(4)(5) (0214)(3)(5) (0215)(3)(4) (0321)(4)(5) (0341)(2)(5) (0351)(2)(4) (0342)(1)(5) (0352)(1)(4) (0345)(1)(2) (0354)(1)(2) (0324)(1)(5) (0325)(1)(4) (0312)(4)(5) (0314)(2)(5) (0315)(2)(4) (0421)(3)(5) (0431)(2)(5) (0451)(2)(3) (0432)(1)(5) (0452)(1)(3) (0453)(1)(2) (0435)(1)(2) (0423)(1)(5) (0425)(1)(3) (0412)(3)(5) (0413)(2)(5) (0415)(2)(3) (0521)(3)(4) (0531)(2)(4) (0541)(2)(3) (0532)(1)(4) (0542)(1)(3) (0543)(1)(2) (0534)(1)(2) (0523)(1)(4) (0524)(1)(3) (0512)(3)(4) (0513)(2)(4) (0514)(2)(3)
1,2,3: (0)(12)(345) (0)(12)(354) (0)(123)(45) (0)(124)(35) (0)(125)(34) (0)(132)(45) (0)(13)(245) (0)(135)(24) (0)(13)(254) (0)(134)(25) (0)(142)(35) (0)(145)(23) (0)(14)(235) (0)(143)(25) (0)(14)(253) (0)(152)(34) (0)(154)(23) (0)(15)(234) (0)(153)(24) (0)(15)(243) (01)(2)(345) (01)(2)(354) (01)(234)(5) (01)(235)(4) (01)(243)(5) (01)(245)(3) (01)(253)(4) (01)(254)(3) (012)(3)(45) (012)(34)(5) (012)(35)(4) (013)(2)(45) (013)(24)(5) (013)(25)(4) (014)(2)(35) (014)(23)(5) (014)(25)(3) (015)(2)(34) (015)(23)(4) (015)(24)(3) (021)(3)(45) (021)(34)(5) (021)(35)(4) (02)(1)(345) (02)(1)(354) (023)(1)(45) (024)(1)(35) (025)(1)(34) (02)(134)(5) (02)(135)(4) (024)(13)(5) (025)(13)(4) (02)(143)(5) (02)(145)(3) (023)(14)(5) (025)(14)(3) (02)(153)(4) (02)(154)(3) (023)(15)(4) (024)(15)(3) (031)(2)(45) (031)(24)(5) (031)(25)(4) (032)(1)(45) (03)(1)(245) (035)(1)(24) (03)(1)(254) (034)(1)(25) (034)(12)(5) (035)(12)(4) (03)(124)(5) (03)(125)(4) (032)(14)(5) (03)(142)(5) (03)(145)(2) (035)(14)(2) (032)(15)(4) (03)(152)(4) (03)(154)(2) (034)(15)(2) (041)(2)(35) (041)(23)(5) (041)(25)(3) (042)(1)(35) (045)(1)(23) (04)(1)(235) (043)(1)(25) (04)(1)(253) (043)(12)(5) (045)(12)(3) (04)(123)(5) (04)(125)(3) (042)(13)(5) (04)(132)(5) (045)(13)(2) (04)(135)(2) (042)(15)(3) (04)(152)(3) (043)(15)(2) (04)(153)(2) (051)(2)(34) (051)(23)(4) (051)(24)(3) (052)(1)(34) (054)(1)(23) (05)(1)(234) (053)(1)(24) (05)(1)(243) (053)(12)(4) (054)(12)(3) (05)(123)(4) (05)(124)(3) (052)(13)(4) (05)(132)(4) (054)(13)(2) (05)(134)(2) (052)(14)(3) (05)(142)(3) (053)(14)(2) (05)(143)(2)
1,5: (0)(12345) (0)(12453) (0)(12534) (0)(13542) (0)(13254) (0)(13425) (0)(14352) (0)(14523) (0)(14235) (0)(15432) (0)(15243) (0)(15324) (01235)(4) (01243)(5) (01254)(3) (01352)(4) (01345)(2) (01324)(5) (01432)(5) (01453)(2) (01425)(3) (01542)(3) (01534)(2) (01523)(4) (02341)(5) (02451)(3) (02531)(4) (02354)(1) (02435)(1) (02543)(1) (02134)(5) (02413)(5) (02145)(3) (02514)(3) (02153)(4) (02315)(4) (03421)(5) (03541)(2) (03251)(4) (03452)(1) (03245)(1) (03524)(1) (03512)(4) (03125)(4) (03142)(5) (03214)(5) (03154)(2) (03415)(2) (04521)(3) (04351)(2) (04231)(5) (04532)(1) (04253)(1) (04325)(1) (04312)(5) (04123)(5) (04513)(2) (04135)(2) (04152)(3) (04215)(3) (05321)(4) (05431)(2) (05241)(3) (05342)(1) (05423)(1) (05234)(1) (05412)(3) (05124)(3) (05132)(4) (05213)(4) (05143)(2) (05314)(2)
1,5: (0)(12354) (0)(12435) (0)(12543) (0)(13452) (0)(13245) (0)(13524) (0)(14532) (0)(14253) (0)(14325) (0)(15342) (0)(15423) (0)(15234) (01234)(5) (01245)(3) (01253)(4) (01342)(5) (01354)(2) (01325)(4) (01452)(3) (01435)(2) (01423)(5) (01532)(4) (01543)(2) (01524)(3) (02351)(4) (02431)(5) (02541)(3) (02345)(1) (02453)(1) (02534)(1) (02135)(4) (02513)(4) (02143)(5) (02314)(5) (02154)(3) (02415)(3) (03521)(4) (03451)(2) (03241)(5) (03542)(1) (03254)(1) (03425)(1) (03412)(5) (03124)(5) (03145)(2) (03514)(2) (03152)(4) (03215)(4) (04321)(5) (04531)(2) (04251)(3) (04352)(1) (04523)(1) (04235)(1) (04512)(3) (04125)(3) (04132)(5) (04213)(5) (04153)(2) (04315)(2) (05421)(3) (05341)(2) (05231)(4) (05432)(1) (05243)(1) (05324)(1) (05312)(4) (05123)(4) (05413)(2) (05134)(2) (05142)(3) (05214)(3)
2,2,2: (01)(23)(45) (01)(24)(35) (01)(25)(34) (02)(13)(45) (02)(14)(35) (02)(15)(34) (03)(12)(45) (03)(14)(25) (03)(15)(24) (04)(12)(35) (04)(13)(25) (04)(15)(23) (05)(12)(34) (05)(13)(24) (05)(14)(23)
2,4: (01)(2345) (01)(2354) (01)(2453) (01)(2435) (01)(2543) (01)(2534) (0123)(45) (0124)(35) (0125)(34) (0132)(45) (0135)(24) (0134)(25) (0142)(35) (0145)(23) (0143)(25) (0152)(34) (0154)(23) (0153)(24) (0231)(45) (0241)(35) (0251)(34) (02)(1345) (02)(1354) (0213)(45) (0245)(13) (0254)(13) (02)(1453) (02)(1435) (0214)(35) (0235)(14) (0253)(14) (02)(1543) (02)(1534) (0215)(34) (0234)(15) (0243)(15) (0321)(45) (0351)(24) (0341)(25) (0312)(45) (0345)(12) (0354)(12) (03)(1245) (03)(1254) (0352)(14) (03)(1452) (03)(1425) (0314)(25) (0325)(14) (0342)(15) (03)(1542) (03)(1524) (0315)(24) (0324)(15) (0421)(35) (0451)(23) (0431)(25) (0412)(35) (0453)(12) (0435)(12) (04)(1235) (04)(1253) (0452)(13) (04)(1352) (0413)(25) (0425)(13) (04)(1325) (0432)(15) (04)(1532) (0423)(15) (04)(1523) (0415)(23) (0521)(34) (0541)(23) (0531)(24) (0512)(34) (0543)(12) (0534)(12) (05)(1234) (05)(1243) (0542)(13) (05)(1342) (0513)(24) (0524)(13) (05)(1324) (0532)(14) (05)(1432) (0523)(14) (05)(1423) (0514)(23)
3,3: (012)(345) (012)(354) (013)(245) (013)(254) (014)(235) (014)(253) (015)(234) (015)(243) (021)(345) (021)(354) (024)(135) (025)(134) (023)(145) (025)(143) (023)(154) (024)(153) (031)(245) (031)(254) (035)(124) (034)(125) (032)(145) (035)(142) (032)(154) (034)(152) (041)(235) (041)(253) (045)(123) (043)(125) (042)(135) (045)(132) (042)(153) (043)(152) (051)(234) (051)(243) (054)(123) (053)(124) (052)(134) (054)(132) (052)(143) (053)(142)
6: (012345) (012354) (012453) (012435) (012543) (012534) (013452) (013542) (013245) (013524) (013254) (013425) (014532) (014352) (014523) (014235) (014253) (014325) (015432) (015342) (015423) (015234) (015243) (015324) (023451) (023541) (024531) (024351) (025431) (025341) (021345) (021354) (024513) (024135) (025413) (025134) (021453) (021435) (023145) (023514) (025143) (025314) (021543) (021534) (023154) (023415) (024153) (024315) (034521) (035421) (032451) (035241) (032541) (034251) (034512) (035412) (031245) (035124) (031254) (034125) (031452) (035142) (032145) (035214) (031425) (032514) (031542) (034152) (032154) (034215) (031524) (032415) (045321) (043521) (045231) (042351) (042531) (043251) (045312) (043512) (045123) (041235) (041253) (043125) (045132) (041352) (045213) (042135) (042513) (041325) (043152) (041532) (042153) (043215) (041523) (042315) (054321) (053421) (054231) (052341) (052431) (053241) (054312) (053412) (054123) (051234) (051243) (053124) (054132) (051342) (054213) (052134) (052413) (051324) (053142) (051432) (052143) (053214) (051423) (052314)
大体 S_6 の共役類と同じだが,長さ 5 の巡回置換だけ 2 つの軌道に分かれている.

ここまでは規則的なので未証明で実装してみよう → WA

追加実験:

n = 7
1,1,1,1,1,1,1: (0)(1)(2)(3)(4)(5)(6)
1,1,1,1,1,2: (0)(1)(2)(3)(4)(56)
1,1,1,1,3: (0)(1)(2)(3)(456)
1,1,1,2,2: (0)(1)(2)(34)(56)
1,1,1,4: (0)(1)(2)(3456)
1,1,2,3: (0)(1)(23)(456)
1,1,5: (0)(1)(23456)
1,2,2,2: (0)(12)(34)(56)
1,2,4: (0)(12)(3456)
1,3,3: (0)(123)(456)
1,6: (0)(123456)
2,2,3: (01)(23)(456)
2,5: (01)(23456)
3,4: (012)(3456)
7: (0123456)
7: (0123465)

n = 8
1,1,1,1,1,1,1,1: (0)(1)(2)(3)(4)(5)(6)(7)
1,1,1,1,1,1,2: (0)(1)(2)(3)(4)(5)(67)
1,1,1,1,1,3: (0)(1)(2)(3)(4)(567)
1,1,1,1,2,2: (0)(1)(2)(3)(45)(67)
1,1,1,1,4: (0)(1)(2)(3)(4567)
1,1,1,2,3: (0)(1)(2)(34)(567)
1,1,1,5: (0)(1)(2)(34567)
1,1,2,2,2: (0)(1)(23)(45)(67)
1,1,2,4: (0)(1)(23)(4567)
1,1,3,3: (0)(1)(234)(567)
1,1,6: (0)(1)(234567)
1,2,2,3: (0)(12)(34)(567)
1,2,5: (0)(12)(34567)
1,3,4: (0)(123)(4567)
1,7: (0)(1234567)
1,7: (0)(1234576)
2,2,2,2: (01)(23)(45)(67)
2,2,4: (01)(23)(4567)
2,3,3: (01)(234)(567)
2,6: (01)(234567)
3,5: (012)(34567)
3,5: (012)(34576)
4,4: (0123)(4567)
8: (01234567)

長さ奇数のサイクル 2 つ以下に分かれるようなタイプが 2 つの軌道に分解するみたい.

*/


//【置換の数え上げ(型指定)】O(k)
/*
* 自然数の分割 p[0..k)(広義単調減少)で表される型をもつ置換の個数を返す.
*
* 制約 : fm は (Σp[0..k))! まで計算可能であること.
*/
mint count_permutation_type(const vi& p, const Factorial_mint& fm) {
	// verify : https://atcoder.jp/contests/abc226/tasks/abc226_f

	//【方法】
	// n = Σp[0..k) とおく.求める置換の個数は次の (1), (2), (3) の計算で得られる:
	// 
	// (1) 各 p[i] に対応する巡回置換に [0..n) のどの元を割り当てるかが多項係数 (n, [p[0..k)]) 通り.
	// (2) p[i] に対応する巡回置換の中でどの順に並べるかが (p[i] - 1)! 通り.(円順列)
	// (3) 同じ長さの巡回置換には区別は無いので,各長さごとに (個数)! で割り引く.
	//
	// 実際には (1) の分母と (2) の分子は打ち消し合い,残るのは分母の p[i] のみである.

	int k = sz(p);

	// n : 置換の大きさ,cnt : 各長さごとの個数,dnm : 分母
	int n = 0, cnt = 0; mint dnm = 1;

	rep(i, k) {
		// 置換の大きさを更新する.
		n += p[i];

		// (1) の分母と (2) の分子が打ち消し合い残った分母の p[i] を掛けておく.
		dnm *= p[i];

		// 新しい長さに変わったらそれまでの (個数)! を分母に掛けておく.
		if (i > 0 && p[i - 1] != p[i]) {
			dnm *= fm.fact(cnt);
			cnt = 1;
		}
		else cnt++;
	}
	dnm *= fm.fact(cnt);

	return fm.fact(n) / dnm;
}


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");

//	zikken();

	int n;
	cin >> n;

	vi p(n);
	cin >> p;
	--p;

	if (n <= 2) EXIT(1);

	Factorial_mint fm(n);

	auto cycles = permutation_decomposition(p);
	
	vi type;
	repe(cycle, cycles) type.push_back(sz(cycle));
	sort(all(type), greater<int>());

	mint res = count_permutation_type(type, fm);
	vi cnt(2);
	repe(len, type) cnt[len % 2]++;
	if (cnt[0] == 0 && cnt[1] <= 2) res /= 2;

	cout << res << endl;
}
0