Submission #70197666
Source Code Expand
//utf-8 c++14
/*
+ - * / ^ io only, mod is prime, 2 * mod <= u32 max
*/
#include <cstdint>
#include <type_traits>
#include <limits>
#include <numeric>
#include <iostream>
#define ILCST inline constexpr
#define TMILCST template <u32 mod> ILCST
#define ILCSTMR ILCST modint&
#define NT noexcept
namespace modint_nm {
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using umx = std::uintmax_t;
using i32 = std::int32_t;
using imx = std::intmax_t;
template <u32 mod, typename type, typename = void> struct modval_t
{ static ILCST u32 modval(type v) NT { return v % mod; } };
template <u32 mod, typename type> struct modval_t <mod, type, std::enable_if_t<std::is_unsigned<type>::value> >
{ static ILCST u32 modval(type v) NT { return v % mod; } };
template <u32 mod, typename type> struct modval_t <mod, type, std::enable_if_t<std::is_signed<type>::value> >
{ static ILCST u32 modval(type v) NT { v %= i32(mod);return v < 0? v + mod : v; } };
template <u32 mod, typename type> struct modval_t <mod, type, std::enable_if_t<std::is_floating_point<type>::value> >
{ static ILCST u32 modval(type v) NT { return modval_t<mod, imx>::modval(imx(v)); } };
template <u32 mod> struct modval_t <mod, __int128_t>
{ static ILCST u32 modval(__int128_t v) NT { v %= i32(mod);return v < 0? v + mod : v; } };
template <u32 mod> struct modval_t <mod, __uint128_t>
{ static ILCST u32 modval(__uint128_t v) NT { return v % mod; } };
TMILCST void modsplus(u32 &a, u32 b) NT { a += b;if (a >= mod)a -= mod; }
TMILCST u32 modplus(u32 a, u32 b) NT { a += b;return a >= mod? a - mod : a; }
TMILCST void modssubt(u32 &a, u32 b) NT { if (a < b)a += mod - b; else a -= b; }
TMILCST u32 modsubt(u32 a, u32 b) NT { return a < b? a + (mod - b) : a - b; }
TMILCST u32 modmult(u32 a, u32 b) NT { return u64(a) * b % mod; }
TMILCST u32 modfpow(u32 a, umx b) NT
{ u32 ret = 1;for (; b; b >>= 1, a = modmult<mod>(a, a))if (b & 1)ret = modmult<mod>(ret, a);return ret; }
// 假定值在模范围内,减少一次取模操作
struct in_mod_range_t { } in_mod_range;
template <u32> struct modint;
template <u32 mod, typename _T>
ILCST modint<mod> operator ^ (modint<mod> a, modint<mod - 1> b) NT;
template <u32 mod_>
struct modint {
static constexpr u32 mod = mod_;
typedef void is_modint_t;
u32 val;
ILCST modint() NT : val() { }
template <typename Val_t> ILCST modint(Val_t Val) NT : val(modval_t<mod, Val_t>::modval(Val)) {}
ILCST modint(const modint &) NT = default;
ILCST modint(modint &&) NT = default;
ILCST modint(in_mod_range_t, u32 v) NT : val{v} {}
template <typename Val_t> ILCST modint &operator = (Val_t Val) NT
{ val = modval_t<mod, Val_t>::modval(Val);return *this; }
ILCSTMR operator = (const modint &) NT = default;
ILCSTMR operator = (modint &&) NT = default;
ILCSTMR operator += (modint o) NT { modsplus<mod>(val, o.val);return *this; }
ILCSTMR operator -= (modint o) NT { modssubt<mod>(val, o.val);return *this; }
ILCSTMR operator *= (modint o) NT { val = modmult<mod>(val, o.val);return *this; }
ILCSTMR operator ^= (modint<mod - 1> o) NT
{ val = modfpow<mod>(val, modint<mod - 1>(o).value());return *this; }
ILCST modint operator - () const NT { return modint(in_mod_range, val? mod - val : 0u); }
ILCST modint inv() const NT { return (*this) ^ (mod - 2); }
ILCSTMR operator /= (modint o) NT { val = modmult<mod>(val, o.inv().val);return *this; }
ILCST u32 value() const NT { return val; }
ILCST operator u32 () const NT { return val; }
template <typename _Tp> ILCST operator _Tp () const NT { return (_Tp)val; }
ILCSTMR plussubt(bool v, modint x) NT //+=(-1)^v*x
{ if (v)*this -= x; else *this += x; return *this; }
template <typename _Tp, typename = std::enable_if_t<std::is_integral<_Tp>::value> >
ILCSTMR plussubt(_Tp v, modint x) NT //+=(-1)^v*x
{ if (v & 1)*this -= x; else *this += x; return *this; }
static constexpr modint nan = modint(in_mod_range, mod);
}; // __is_trivially_copyable(modint<...>) = true
template <u32 mod> constexpr u32 modint<mod>::mod;
template <u32 mod> constexpr modint<mod> modint<mod>::nan;
#define DEFOPT(opt, expr)\
TMILCST modint<mod> operator opt (modint<mod> a, modint<mod> b) NT\
{ return modint<mod>(in_mod_range, expr); }\
template <u32 mod, typename _T> ILCST modint<mod> operator opt (_T a, modint<mod> b) NT\
{ return modint<mod>(a) opt b; }\
template <u32 mod, typename _T> ILCST modint<mod> operator opt (modint<mod> a, _T b) NT\
{ return a opt modint<mod>(b); }
DEFOPT(+, modplus<mod>(a.val, b.val))
DEFOPT(-, modsubt<mod>(a.val, b.val))
DEFOPT(*, modmult<mod>(a.val, b.val))
DEFOPT(/, modmult<mod>(a.val, b.inv().val))
TMILCST modint<mod> operator ^ (modint<mod> a, modint<mod - 1> b) NT
{ return modint<mod>(in_mod_range, modfpow<mod>(a.val, modint<mod - 1>(b).value())); }
TMILCST modint<mod> fma(modint<mod> a, modint<mod> b, modint<mod> c) NT
{ return modint<mod>(in_mod_range, (u64(a.val) * b.val + c.val) % mod); }
template <u32 mod> // a += b * c
ILCST void splusmult(modint<mod> &a, modint<mod> b, modint<mod> c) NT { a = fma(b, c, a); }
template <typename iter_t>
using is_modint_iter = std::enable_if_t<std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<iter_t>::iterator_category>::value, typename std::iterator_traits<iter_t>::value_type::is_modint_t>;
template <typename iter_t, typename = is_modint_iter<iter_t> >
constexpr void calc_fact(u32 n, iter_t fc){//let fc_i = i!, 0<=i<n
if (n == 0)return;
*fc = 1;
for (u32 i = 1; i < n; ++i)fc[i] = fc[i - 1] * i;
}
inline namespace predefine_modint {
using modp0 = modint<998244353>;
using modp1 = modint<1000000007>;
}
}
namespace std {
using u32 = std::uint32_t;
using u64 = std::uint64_t;
template <u32 mod> ostream &operator << (ostream &os, modint_nm::modint<mod> v){ return os << v.value(); }
template <u32 mod> istream &operator >> (istream &is, modint_nm::modint<mod> &v){ u64 x;is >> x;v = x;return is; }
}
#include <bits/stdc++.h>
using namespace std;
using mod = modint_nm::modp0;
mod fc[3010];
int n;
bool b[3010];//b_i? i<-p_i : i->p_i
int p[3010];//i-p_i
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
{//calc `p`, `b`
static int a[3010], b[3010], c[3010];
for (int i = 1; i <= n; ++i)cin >> a[i], c[(a[i] + 1) >> 1] = i;
if (count(c + 1, c + n + 1, 0)){
cout << 0 << endl;
return 0;
}
for (int i = 1; i <= n; ++i)cin >> b[i];
for (int i = 1; i <= n; ++i){
::b[i] = a[c[i]] & 1;
p[i] = b[c[i]] == -1? 0 : (b[c[i]] + 1 >> 1);
}
}
int c0 = 0, c1 = 0, c2 = 0;//count only =0, only =1, both
{//calc `c0,c1,c2`
static bool v[3010];
fill_n(v + 1, n, 0);
for (int i = 1; i <= n; ++i)v[p[i]] = 1;
static bool vs[3010];
fill_n(vs + 1, n, 0);
for (int i = 1; i <= n; ++i)if (!v[i]){//enum lists
int ms = 0;
for (int u = i; u; u = p[u])vs[u] = 1, ms |= 1 << ::b[u];
++(ms == 1? c0 : ms == 2? c1 : c2);
}
for (int i = 1; i <= n; ++i)if (!vs[i]){
int ms = 0;
for (int u = i; !vs[u]; u = p[u])vs[u] = 1, ms |= 1 << ::b[u];
if (ms < 3){
cout << 0 << endl;
return 0;
}
}
}
modint_nm::calc_fact(n + 1, fc);
constexpr mod f[2]{1, -1};
mod rs = 0;
for (int i = 0; i <= 1 && i <= c0; ++i)
for (int j = 0; j <= 1 && j <= c1; ++j)
rs += (i? c0 : 1) * (j? c1 : 1) * f[i] * f[j] * fc[c0 - i + c1 - j + c2];
cout << rs << endl;
return 0;
}
Submission Info
| Submission Time |
|
| Task |
D - Mirror and Order |
| User |
szt100309 |
| Language |
C++ 20 (gcc 12.2) |
| Score |
1000 |
| Code Size |
8549 Byte |
| Status |
AC |
| Exec Time |
2 ms |
| Memory |
3696 KiB |
Compile Error
Main.cpp: In function ‘int main()’:
Main.cpp:164:48: warning: suggest parentheses around ‘+’ inside ‘>>’ [-Wparentheses]
164 | p[i] = b[c[i]] == -1? 0 : (b[c[i]] + 1 >> 1);
| ~~~~~~~~^~~
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
1000 / 1000 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
sample-01.txt, sample-02.txt |
| All |
in-01.txt, in-02.txt, in-03.txt, in-04.txt, in-05.txt, in-06.txt, in-07.txt, in-08.txt, in-09.txt, in-10.txt, in-11.txt, in-12.txt, in-13.txt, in-14.txt, in-15.txt, in-16.txt, in-17.txt, in-18.txt, in-19.txt, in-20.txt, in-21.txt, in-22.txt, in-23.txt, in-24.txt, in-25.txt, in-26.txt, in-27.txt, in-28.txt, in-29.txt, in-30.txt, in-31.txt, in-32.txt, in-33.txt, in-34.txt, in-35.txt, in-36.txt, in-37.txt, in-38.txt, in-39.txt, in-40.txt, in-41.txt, in-42.txt, in-43.txt, in-44.txt, in-45.txt, in-46.txt, in-47.txt, sample-01.txt, sample-02.txt |
| Case Name |
Status |
Exec Time |
Memory |
| in-01.txt |
AC |
1 ms |
3448 KiB |
| in-02.txt |
AC |
1 ms |
3516 KiB |
| in-03.txt |
AC |
2 ms |
3692 KiB |
| in-04.txt |
AC |
2 ms |
3468 KiB |
| in-05.txt |
AC |
1 ms |
3464 KiB |
| in-06.txt |
AC |
1 ms |
3424 KiB |
| in-07.txt |
AC |
1 ms |
3572 KiB |
| in-08.txt |
AC |
1 ms |
3500 KiB |
| in-09.txt |
AC |
1 ms |
3576 KiB |
| in-10.txt |
AC |
1 ms |
3492 KiB |
| in-11.txt |
AC |
2 ms |
3548 KiB |
| in-12.txt |
AC |
2 ms |
3492 KiB |
| in-13.txt |
AC |
1 ms |
3464 KiB |
| in-14.txt |
AC |
1 ms |
3504 KiB |
| in-15.txt |
AC |
2 ms |
3620 KiB |
| in-16.txt |
AC |
2 ms |
3584 KiB |
| in-17.txt |
AC |
2 ms |
3648 KiB |
| in-18.txt |
AC |
1 ms |
3584 KiB |
| in-19.txt |
AC |
2 ms |
3484 KiB |
| in-20.txt |
AC |
2 ms |
3496 KiB |
| in-21.txt |
AC |
1 ms |
3588 KiB |
| in-22.txt |
AC |
1 ms |
3560 KiB |
| in-23.txt |
AC |
1 ms |
3488 KiB |
| in-24.txt |
AC |
1 ms |
3540 KiB |
| in-25.txt |
AC |
2 ms |
3696 KiB |
| in-26.txt |
AC |
2 ms |
3584 KiB |
| in-27.txt |
AC |
1 ms |
3632 KiB |
| in-28.txt |
AC |
2 ms |
3560 KiB |
| in-29.txt |
AC |
1 ms |
3440 KiB |
| in-30.txt |
AC |
2 ms |
3468 KiB |
| in-31.txt |
AC |
1 ms |
3604 KiB |
| in-32.txt |
AC |
1 ms |
3512 KiB |
| in-33.txt |
AC |
1 ms |
3492 KiB |
| in-34.txt |
AC |
2 ms |
3636 KiB |
| in-35.txt |
AC |
1 ms |
3560 KiB |
| in-36.txt |
AC |
1 ms |
3444 KiB |
| in-37.txt |
AC |
1 ms |
3564 KiB |
| in-38.txt |
AC |
1 ms |
3556 KiB |
| in-39.txt |
AC |
1 ms |
3560 KiB |
| in-40.txt |
AC |
1 ms |
3456 KiB |
| in-41.txt |
AC |
1 ms |
3432 KiB |
| in-42.txt |
AC |
1 ms |
3648 KiB |
| in-43.txt |
AC |
1 ms |
3504 KiB |
| in-44.txt |
AC |
1 ms |
3544 KiB |
| in-45.txt |
AC |
1 ms |
3636 KiB |
| in-46.txt |
AC |
2 ms |
3492 KiB |
| in-47.txt |
AC |
2 ms |
3540 KiB |
| sample-01.txt |
AC |
1 ms |
3432 KiB |
| sample-02.txt |
AC |
1 ms |
3452 KiB |