#ifndef HIDDEN_IN_VS // 折りたたみ用 // 警告の抑制 #define _CRT_SECURE_NO_WARNINGS // ライブラリの読み込み #include 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; using pll = pair; using pil = pair; using pli = pair; using vi = vector; using vvi = vector; using vvvi = vector; using vvvvi = vector; using vl = vector; using vvl = vector; using vvvl = vector; using vvvvl = vector; using vb = vector; using vvb = vector; using vvvb = vector; using vc = vector; using vvc = vector; using vvvc = vector; using vd = vector; using vvd = vector; using vvvd = vector; template using priority_queue_rev = priority_queue, greater>; 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 inline ll pow(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; } template inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新(更新されたら true を返す) template inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新(更新されたら true を返す) template inline T get(T set, int i) { return (set >> i) & T(1); } // 演算子オーバーロード template inline istream& operator>>(istream& is, pair& p) { is >> p.first >> p.second; return is; } template inline istream& operator>>(istream& is, vector& v) { repea(x, v) is >> x; return is; } template inline vector& operator--(vector& v) { repea(x, v) --x; return v; } template inline vector& operator++(vector& v) { repea(x, v) ++x; return v; } #endif // 折りたたみ用 #if __has_include() #include 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; using vvm = vector; using vvvm = vector; using vvvvm = vector; #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 ll inversion_number(const vector& a) { // verify : https://atcoder.jp/contests/arc075/tasks/arc075_c int n = sz(a); // 値 a[i] と位置 i を組にしソートする. vector> ai(n); rep(i, n) ai[i] = { a[i], i }; sort(all(ai)); ll res = 0; // ft[i] : いままでに位置 i の要素が現れたか fenwick_tree 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 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()); 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; }