QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#646657 | #9. 简单回路 | maspy | 40 | 15ms | 4696kb | C++23 | 27.5kb | 2024-10-17 02:36:47 | 2024-10-17 02:36:48 |
Judging History
answer
#line 1 "/home/maspy/compro/library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない?
// #pragma GCC target("avx2,popcnt")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;
template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;
using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)
#define FOR_subset(t, s) for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define stoi stoll
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
template <typename T>
T floor(T a, T b) {
return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
T q = floor(x, y);
return {q, x - q * y};
}
template <typename T, typename U>
T SUM(const vector<U> &A) {
T sm = 0;
for (auto &&a: A) sm += a;
return sm;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()
template <typename T>
T POP(deque<T> &que) {
T a = que.front();
que.pop_front();
return a;
}
template <typename T>
T POP(pq<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(pqg<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(vc<T> &que) {
T a = que.back();
que.pop_back();
return a;
}
template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
if (check_ok) assert(check(ok));
while (abs(ok - ng) > 1) {
auto x = (ng + ok) / 2;
(check(x) ? ok : ng) = x;
}
return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
FOR(iter) {
double x = (ok + ng) / 2;
(check(x) ? ok : ng) = x;
}
return (ok + ng) / 2;
}
template <class T, class S>
inline bool chmax(T &a, const S &b) {
return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
return (a > b ? a = b, 1 : 0);
}
// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
vc<int> A(S.size());
FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
return A;
}
template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
int N = A.size();
vector<T> B(N + 1);
FOR(i, N) { B[i + 1] = B[i] + A[i]; }
if (off == 0) B.erase(B.begin());
return B;
}
// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
vector<int> ids(len(A));
iota(all(ids), 0);
sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
return ids;
}
// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
vc<T> B(len(I));
FOR(i, len(I)) B[i] = A[I[i]];
return B;
}
template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &... others) {
vc<T> &res = first;
(res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
#line 1 "/home/maspy/compro/library/other/io.hpp"
#define FASTIO
#include <unistd.h>
// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;
struct Pre {
char num[10000][4];
constexpr Pre() : num() {
for (int i = 0; i < 10000; i++) {
int n = i;
for (int j = 3; j >= 0; j--) {
num[i][j] = n % 10 | '0';
n /= 10;
}
}
}
} constexpr pre;
inline void load() {
memcpy(ibuf, ibuf + pil, pir - pil);
pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
pil = 0;
if (pir < SZ) ibuf[pir++] = '\n';
}
inline void flush() {
fwrite(obuf, 1, por, stdout);
por = 0;
}
void rd(char &c) {
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
}
void rd(string &x) {
x.clear();
char c;
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
do {
x += c;
if (pil == pir) load();
c = ibuf[pil++];
} while (!isspace(c));
}
template <typename T>
void rd_real(T &x) {
string s;
rd(s);
x = stod(s);
}
template <typename T>
void rd_integer(T &x) {
if (pil + 100 > pir) load();
char c;
do
c = ibuf[pil++];
while (c < '-');
bool minus = 0;
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (c == '-') { minus = 1, c = ibuf[pil++]; }
}
x = 0;
while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (minus) x = -x;
}
}
void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }
template <class T, class U>
void rd(pair<T, U> &p) {
return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
if constexpr (N < std::tuple_size<T>::value) {
auto &x = std::get<N>(t);
rd(x);
rd_tuple<N + 1>(t);
}
}
template <class... T>
void rd(tuple<T...> &tpl) {
rd_tuple(tpl);
}
template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
for (auto &d: x) rd(d);
}
void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
rd(h), read(t...);
}
void wt(const char c) {
if (por == SZ) flush();
obuf[por++] = c;
}
void wt(const string s) {
for (char c: s) wt(c);
}
void wt(const char *s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) wt(s[i]);
}
template <typename T>
void wt_integer(T x) {
if (por > SZ - 100) flush();
if (x < 0) { obuf[por++] = '-', x = -x; }
int outi;
for (outi = 96; x >= 10000; outi -= 4) {
memcpy(out + outi, pre.num[x % 10000], 4);
x /= 10000;
}
if (x >= 1000) {
memcpy(obuf + por, pre.num[x], 4);
por += 4;
} else if (x >= 100) {
memcpy(obuf + por, pre.num[x] + 1, 3);
por += 3;
} else if (x >= 10) {
int q = (x * 103) >> 10;
obuf[por] = q | '0';
obuf[por + 1] = (x - q * 10) | '0';
por += 2;
} else
obuf[por++] = x | '0';
memcpy(obuf + por, out + outi + 4, 96 - outi);
por += 96 - outi;
}
template <typename T>
void wt_real(T x) {
ostringstream oss;
oss << fixed << setprecision(15) << double(x);
string s = oss.str();
wt(s);
}
void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }
template <class T, class U>
void wt(const pair<T, U> val) {
wt(val.first);
wt(' ');
wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
if constexpr (N < std::tuple_size<T>::value) {
if constexpr (N > 0) { wt(' '); }
const auto x = std::get<N>(t);
wt(x);
wt_tuple<N + 1>(t);
}
}
template <class... T>
void wt(tuple<T...> tpl) {
wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
template <class T>
void wt(const vector<T> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
wt(head);
if (sizeof...(Tail)) wt(' ');
print(forward<Tail>(tail)...);
}
// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;
#if defined(LOCAL)
#define SHOW(...) SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) print(#x, "=", (x)), flush()
#define SHOW2(x, y) print(#x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) print(#x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v)), flush()
#define SHOW6(x, y, z, w, v, u) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v), #u, "=", (u)), flush()
#else
#define SHOW(...)
#endif
#define INT(...) \
int __VA_ARGS__; \
read(__VA_ARGS__)
#define LL(...) \
ll __VA_ARGS__; \
read(__VA_ARGS__)
#define U32(...) \
u32 __VA_ARGS__; \
read(__VA_ARGS__)
#define U64(...) \
u64 __VA_ARGS__; \
read(__VA_ARGS__)
#define STR(...) \
string __VA_ARGS__; \
read(__VA_ARGS__)
#define CHAR(...) \
char __VA_ARGS__; \
read(__VA_ARGS__)
#define DBL(...) \
double __VA_ARGS__; \
read(__VA_ARGS__)
#define VEC(type, name, size) \
vector<type> name(size); \
read(name)
#define VV(type, name, h, w) \
vector<vector<type>> name(h, vector<type>(w)); \
read(name)
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 2 "/home/maspy/compro/library/mod/modint_common.hpp"
struct has_mod_impl {
template <class T>
static auto check(T &&x) -> decltype(x.get_mod(), std::true_type{});
template <class T>
static auto check(...) -> std::false_type;
};
template <class T>
class has_mod : public decltype(has_mod_impl::check<T>(std::declval<T>())) {};
template <typename mint>
mint inv(int n) {
static const int mod = mint::get_mod();
static vector<mint> dat = {0, 1};
assert(0 <= n);
if (n >= mod) n %= mod;
while (len(dat) <= n) {
int k = len(dat);
int q = (mod + k - 1) / k;
dat.eb(dat[k * q - mod] * mint::raw(q));
}
return dat[n];
}
template <typename mint>
mint fact(int n) {
static const int mod = mint::get_mod();
assert(0 <= n && n < mod);
static vector<mint> dat = {1, 1};
while (len(dat) <= n) dat.eb(dat[len(dat) - 1] * mint::raw(len(dat)));
return dat[n];
}
template <typename mint>
mint fact_inv(int n) {
static vector<mint> dat = {1, 1};
if (n < 0) return mint(0);
while (len(dat) <= n) dat.eb(dat[len(dat) - 1] * inv<mint>(len(dat)));
return dat[n];
}
template <class mint, class... Ts>
mint fact_invs(Ts... xs) {
return (mint(1) * ... * fact_inv<mint>(xs));
}
template <typename mint, class Head, class... Tail>
mint multinomial(Head &&head, Tail &&... tail) {
return fact<mint>(head) * fact_invs<mint>(std::forward<Tail>(tail)...);
}
template <typename mint>
mint C_dense(int n, int k) {
static vvc<mint> C;
static int H = 0, W = 0;
auto calc = [&](int i, int j) -> mint {
if (i == 0) return (j == 0 ? mint(1) : mint(0));
return C[i - 1][j] + (j ? C[i - 1][j - 1] : 0);
};
if (W <= k) {
FOR(i, H) {
C[i].resize(k + 1);
FOR(j, W, k + 1) { C[i][j] = calc(i, j); }
}
W = k + 1;
}
if (H <= n) {
C.resize(n + 1);
FOR(i, H, n + 1) {
C[i].resize(W);
FOR(j, W) { C[i][j] = calc(i, j); }
}
H = n + 1;
}
return C[n][k];
}
template <typename mint, bool large = false, bool dense = false>
mint C(ll n, ll k) {
assert(n >= 0);
if (k < 0 || n < k) return 0;
if constexpr (dense) return C_dense<mint>(n, k);
if constexpr (!large) return multinomial<mint>(n, k, n - k);
k = min(k, n - k);
mint x(1);
FOR(i, k) x *= mint(n - i);
return x * fact_inv<mint>(k);
}
template <typename mint, bool large = false>
mint C_inv(ll n, ll k) {
assert(n >= 0);
assert(0 <= k && k <= n);
if (!large) return fact_inv<mint>(n) * fact<mint>(k) * fact<mint>(n - k);
return mint(1) / C<mint, 1>(n, k);
}
// [x^d](1-x)^{-n}
template <typename mint, bool large = false, bool dense = false>
mint C_negative(ll n, ll d) {
assert(n >= 0);
if (d < 0) return mint(0);
if (n == 0) { return (d == 0 ? mint(1) : mint(0)); }
return C<mint, large, dense>(n + d - 1, d);
}
#line 3 "/home/maspy/compro/library/mod/modint.hpp"
template <int mod>
struct modint {
static constexpr u32 umod = u32(mod);
static_assert(umod < u32(1) << 31);
u32 val;
static modint raw(u32 v) {
modint x;
x.val = v;
return x;
}
constexpr modint() : val(0) {}
constexpr modint(u32 x) : val(x % umod) {}
constexpr modint(u64 x) : val(x % umod) {}
constexpr modint(u128 x) : val(x % umod) {}
constexpr modint(int x) : val((x %= mod) < 0 ? x + mod : x){};
constexpr modint(ll x) : val((x %= mod) < 0 ? x + mod : x){};
constexpr modint(i128 x) : val((x %= mod) < 0 ? x + mod : x){};
bool operator<(const modint &other) const { return val < other.val; }
modint &operator+=(const modint &p) {
if ((val += p.val) >= umod) val -= umod;
return *this;
}
modint &operator-=(const modint &p) {
if ((val += umod - p.val) >= umod) val -= umod;
return *this;
}
modint &operator*=(const modint &p) {
val = u64(val) * p.val % umod;
return *this;
}
modint &operator/=(const modint &p) {
*this *= p.inverse();
return *this;
}
modint operator-() const { return modint::raw(val ? mod - val : u32(0)); }
modint operator+(const modint &p) const { return modint(*this) += p; }
modint operator-(const modint &p) const { return modint(*this) -= p; }
modint operator*(const modint &p) const { return modint(*this) *= p; }
modint operator/(const modint &p) const { return modint(*this) /= p; }
bool operator==(const modint &p) const { return val == p.val; }
bool operator!=(const modint &p) const { return val != p.val; }
modint inverse() const {
int a = val, b = mod, u = 1, v = 0, t;
while (b > 0) {
t = a / b;
swap(a -= t * b, b), swap(u -= t * v, v);
}
return modint(u);
}
modint pow(ll n) const {
assert(n >= 0);
modint ret(1), mul(val);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul;
n >>= 1;
}
return ret;
}
static constexpr int get_mod() { return mod; }
// (n, r), r は 1 の 2^n 乗根
static constexpr pair<int, int> ntt_info() {
if (mod == 120586241) return {20, 74066978};
if (mod == 167772161) return {25, 17};
if (mod == 469762049) return {26, 30};
if (mod == 754974721) return {24, 362};
if (mod == 880803841) return {23, 211};
if (mod == 943718401) return {22, 663003469};
if (mod == 998244353) return {23, 31};
if (mod == 1004535809) return {21, 836905998};
if (mod == 1045430273) return {20, 363};
if (mod == 1051721729) return {20, 330};
if (mod == 1053818881) return {20, 2789};
return {-1, -1};
}
static constexpr bool can_ntt() { return ntt_info().fi != -1; }
};
#ifdef FASTIO
template <int mod>
void rd(modint<mod> &x) {
fastio::rd(x.val);
x.val %= mod;
// assert(0 <= x.val && x.val < mod);
}
template <int mod>
void wt(modint<mod> x) {
fastio::wt(x.val);
}
#endif
using modint107 = modint<1000000007>;
using modint998 = modint<998244353>;
#line 2 "/home/maspy/compro/library/random/hash_vector.hpp"
#line 2 "/home/maspy/compro/library/random/base.hpp"
u64 RNG_64() {
static uint64_t x_
= uint64_t(chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count()) * 10150724397891781847ULL;
x_ ^= x_ << 7;
return x_ ^= x_ >> 9;
}
u64 RNG(u64 lim) { return RNG_64() % lim; }
ll RNG(ll l, ll r) { return l + RNG_64() % (r - l); }
#line 2 "/home/maspy/compro/library/mod/modint61.hpp"
struct modint61 {
static constexpr u64 mod = (1ULL << 61) - 1;
u64 val;
constexpr modint61() : val(0ULL) {}
constexpr modint61(u32 x) : val(x) {}
constexpr modint61(u64 x) : val(x % mod) {}
constexpr modint61(int x) : val((x < 0) ? (x + static_cast<ll>(mod)) : x) {}
constexpr modint61(ll x) : val(((x %= static_cast<ll>(mod)) < 0) ? (x + static_cast<ll>(mod)) : x) {}
static constexpr u64 get_mod() { return mod; }
modint61 &operator+=(const modint61 &a) {
val = ((val += a.val) >= mod) ? (val - mod) : val;
return *this;
}
modint61 &operator-=(const modint61 &a) {
val = ((val -= a.val) >= mod) ? (val + mod) : val;
return *this;
}
modint61 &operator*=(const modint61 &a) {
const unsigned __int128 y = static_cast<unsigned __int128>(val) * a.val;
val = (y >> 61) + (y & mod);
val = (val >= mod) ? (val - mod) : val;
return *this;
}
modint61 operator-() const { return modint61(val ? mod - val : u64(0)); }
modint61 &operator/=(const modint61 &a) { return (*this *= a.inverse()); }
modint61 operator+(const modint61 &p) const { return modint61(*this) += p; }
modint61 operator-(const modint61 &p) const { return modint61(*this) -= p; }
modint61 operator*(const modint61 &p) const { return modint61(*this) *= p; }
modint61 operator/(const modint61 &p) const { return modint61(*this) /= p; }
bool operator<(const modint61 &other) const { return val < other.val; }
bool operator==(const modint61 &p) const { return val == p.val; }
bool operator!=(const modint61 &p) const { return val != p.val; }
modint61 inverse() const {
ll a = val, b = mod, u = 1, v = 0, t;
while (b > 0) {
t = a / b;
swap(a -= t * b, b), swap(u -= t * v, v);
}
return modint61(u);
}
modint61 pow(ll n) const {
assert(n >= 0);
modint61 ret(1), mul(val);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul, n >>= 1;
}
return ret;
}
};
#ifdef FASTIO
void rd(modint61 &x) {
fastio::rd(x.val);
assert(0 <= x.val && x.val < modint61::mod);
}
void wt(modint61 x) { fastio::wt(x.val); }
#endif
#line 5 "/home/maspy/compro/library/random/hash_vector.hpp"
template <typename T>
u64 hash_vector(vc<T> X) {
using mint = modint61;
static vc<mint> hash_base;
int n = len(X);
while (len(hash_base) <= n) { hash_base.eb(RNG(mint::get_mod())); }
mint H = 0;
FOR(i, n) H += hash_base[i] * mint(X[i]);
H += hash_base[n];
return H.val;
}
template <typename T, int K>
u64 hash_array(array<T, K> X) {
using mint = modint61;
static array<mint, K> hash_base{};
if (hash_base[0] == mint(0)) FOR(i, K) hash_base[i] = RNG_64();
mint H = 0;
FOR(i, K) H += hash_base[i] * mint(X[i]);
return H.val;
}
#line 2 "/home/maspy/compro/library/ds/hashmap.hpp"
// u64 -> Val
template <typename Val>
struct HashMap {
// n は入れたいものの個数で ok
HashMap(u32 n = 0) { build(n); }
void build(u32 n) {
u32 k = 8;
while (k < n * 2) k *= 2;
cap = k / 2, mask = k - 1;
key.resize(k), val.resize(k), used.assign(k, 0);
}
// size を保ったまま. size=0 にするときは build すること.
void clear() {
used.assign(len(used), 0);
cap = (mask + 1) / 2;
}
int size() { return len(used) / 2 - cap; }
int index(const u64& k) {
int i = 0;
for (i = hash(k); used[i] && key[i] != k; i = (i + 1) & mask) {}
return i;
}
Val& operator[](const u64& k) {
if (cap == 0) extend();
int i = index(k);
if (!used[i]) { used[i] = 1, key[i] = k, val[i] = Val{}, --cap; }
return val[i];
}
Val get(const u64& k, Val default_value) {
int i = index(k);
return (used[i] ? val[i] : default_value);
}
bool count(const u64& k) {
int i = index(k);
return used[i] && key[i] == k;
}
// f(key, val)
template <typename F>
void enumerate_all(F f) {
FOR(i, len(used)) if (used[i]) f(key[i], val[i]);
}
private:
u32 cap, mask;
vc<u64> key;
vc<Val> val;
vc<bool> used;
u64 hash(u64 x) {
static const u64 FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count();
x += FIXED_RANDOM;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return (x ^ (x >> 31)) & mask;
}
void extend() {
vc<pair<u64, Val>> dat;
dat.reserve(len(used) / 2 - cap);
FOR(i, len(used)) {
if (used[i]) dat.eb(key[i], val[i]);
}
build(2 * len(dat));
for (auto& [a, b]: dat) (*this)[a] = b;
}
};
#line 2 "/home/maspy/compro/library/ds/unionfind/unionfind.hpp"
struct UnionFind {
int n, n_comp;
vc<int> dat; // par or (-size)
UnionFind(int n = 0) { build(n); }
void build(int m) {
n = m, n_comp = m;
dat.assign(n, -1);
}
void reset() { build(n); }
int operator[](int x) {
while (dat[x] >= 0) {
int pp = dat[dat[x]];
if (pp < 0) { return dat[x]; }
x = dat[x] = pp;
}
return x;
}
ll size(int x) {
x = (*this)[x];
return -dat[x];
}
bool merge(int x, int y) {
x = (*this)[x], y = (*this)[y];
if (x == y) return false;
if (-dat[x] < -dat[y]) swap(x, y);
dat[x] += dat[y], dat[y] = x, n_comp--;
return true;
}
vc<int> get_all() {
vc<int> A(n);
FOR(i, n) A[i] = (*this)[i];
return A;
}
};
#line 7 "main.cpp"
/*
special state
init, end
列の間の辺の状態
-1 辺がない
それ以外:同じ成分の中で最小インデックス
end いらない
init: (-1,-1,...)
*/
using mint = modint107;
void solve() {
LL(N, M, K);
vv(int, dat, 6, N, 1);
FOR(i, M, 6) FOR(j, N) dat[i][j] = 0;
FOR(K) {
INT(x, y);
--x, --y;
dat[y][x] = 0;
}
M = 6;
using ARR = array<int, 6>;
vc<ARR> state;
HashMap<int> MP;
auto get_idx = [&](ARR A) -> int {
u64 k = hash_array<int, 6>(A);
if (!MP.count(k)) {
MP[k] = len(state);
state.eb(A);
}
return MP[k];
};
int init = get_idx({-1, -1, -1, -1, -1, -1});
struct E {
int i, j;
int V, E;
};
vvc<E> edge(64);
FOR(s, 64) edge[s].eb(init, init, 0, 0);
FOR(idx, len(state)) {
ARR A = state[idx];
FOR(s, 32) {
vc<int> deg(6);
FOR(i, 6) if (A[i] >= 0) { deg[i]++; }
UnionFind uf(6);
FOR(j, 6) if (A[j] != -1) uf.merge(j, A[j]);
FOR(i, 5) {
if (s >> i & 1) uf.merge(i, i + 1), deg[i]++, deg[i + 1]++;
}
if (MAX(deg) >= 3) continue;
ARR B = {-1, -1, -1, -1, -1, -1};
FOR(j, 6) {
if (deg[j] % 2 == 0) continue;
B[j] = j;
FOR(i, j) if (B[i] == i && uf[i] == uf[j]) B[j] = i;
}
if (B == state[init]) { continue; }
int k = get_idx(B);
int used = 0;
FOR(i, 6) if (deg[i] > 0) used |= 1 << i;
SHOW(A, B, used);
FOR(v, 64) if (used == (v & used)) edge[v].eb(idx, k, used, s);
}
}
K = len(state);
SHOW(state[1], len(edge[3]));
for (auto& [a, b, v, e]: edge[3]) SHOW(state[a], state[b], v, e);
vc<int> S(N);
FOR(i, N) { FOR(j, 6) S[i] |= dat[j][i] << j; }
// L[n]: [0,n)
// R[n]: [n,N)
vv(mint, L, N + 1, K);
L[0][init] = 1;
FOR(i, N) {
for (auto& [a, b, xx, yy]: edge[S[i]]) L[i + 1][b] += L[i][a];
}
vv(mint, R, N + 1, K);
R[N][init] = 1;
FOR_R(i, N) {
for (auto& [a, b, xx, yy]: edge[S[i]]) R[i][b] += R[i + 1][a];
}
// SHOW(S);
// FOR(i, N + 1) SHOW(i, L[i]);
// FOR(i, N + 1) SHOW(i, R[i]);
INT(Q);
FOR(Q) {
LL(y, x);
--y, --x;
vc<mint> A = L[y];
vc<mint> B = R[y + 1];
int s = 0;
mint ANS = 0;
SHOW(A, B);
for (auto& [a, b, V, E]: edge[S[y]]) {
auto X = state[b];
if (X[x] == -1) continue;
// if (E >> x & 1) { ANS += A[a] * B[b]; }
ANS += A[a] * B[b];
}
print(ANS);
}
}
signed main() { solve(); }
Details
Tip: Click on the bar to expand more detailed information
Pretests
Final Tests
Test #1:
score: 10
Accepted
time: 1ms
memory: 3780kb
input:
100 1 10 68 1 13 1 48 1 51 1 30 1 90 1 74 1 79 1 80 1 63 1 10 73 1 84 1 10 1 44 1 3 1 16 1 17 1 47 1 49 1 94 1
output:
0 0 0 0 0 0 0 0 0 0
result:
ok 10 lines
Test #2:
score: 10
Accepted
time: 1ms
memory: 4316kb
input:
1000 2 10 468 2 177 1 597 1 396 1 548 2 279 1 601 1 349 1 453 2 217 2 100 954 1 468 1 427 2 948 1 739 2 605 2 177 1 20 2 506 1 778 2 141 1 621 1 273 1 203 2 584 2 718 2 371 2 973 2 892 2 374 2 585 2 419 2 953 2 347 2 575 2 353 2 830 1 196 1 603 2 630 2 144 2 84 2 566 1 598 2 749 1 878 1 322 1 250 2 ...
output:
16238 0 775 18044 36018 1580 0 3120 1558 39294 4935 7580 280 338 432 32994 528 10044 31428 525 407 759 16544 68 567 168 38930 380 794 10730 4608 7728 540 2 37148 33794 1118 924 1548 2119 26918 34250 39618 34100 1134 39420 343 39248 495 35244 23288 5980 0 1134 35894 108 205 39800 29088 6783 2744 6960...
result:
ok 100 lines
Test #3:
score: 10
Accepted
time: 1ms
memory: 4256kb
input:
1000 2 10 378 2 63 1 276 2 245 2 826 1 422 1 634 1 970 1 707 1 386 1 100 987 1 262 2 913 1 201 1 685 1 969 2 382 1 460 1 45 1 535 2 54 2 16 2 436 2 668 1 136 1 210 1 660 2 956 1 743 1 549 2 228 2 967 2 624 2 465 1 135 1 854 1 593 1 359 2 941 1 459 1 456 2 763 2 558 2 116 2 38 2 187 2 108 2 749 1 911...
output:
221 221 4872 5934 1071 0 12 6574 765 11074 432 736 2758 1292 7884 4998 1196 1690 2952 10668 2640 282 1818 7224 7848 3220 6840 1494 3220 6438 6018 3472 10200 6784 912 7068 6120 3192 4930 2338 2508 910 2640 120 276 3192 3820 5022 306 4120 2394 8160 4056 8778 420 6550 1007 861 3780 672 0 232 7638 5124 ...
result:
ok 100 lines
Test #4:
score: 10
Accepted
time: 1ms
memory: 4312kb
input:
1000 3 10 186 3 140 3 410 1 639 1 836 2 399 2 432 3 712 1 946 3 958 3 100 203 3 895 1 351 1 503 2 991 1 61 2 760 1 647 3 70 3 75 1 522 2 539 3 417 1 53 2 404 1 467 2 283 1 313 2 793 3 290 2 410 1 827 1 572 1 534 3 765 2 977 1 97 3 797 3 966 3 404 2 479 1 653 3 212 2 164 2 960 1 655 1 304 1 182 1 190...
output:
774407976 694095038 666138398 204700661 487361334 79350260 823916526 764051786 649505956 109016625 819157802 869272506 187719766 93956822 405866989 762991904 313225905 177696788 482536746 637310259 0 626821887 869378231 769919477 251726603 475569128 292349487 564212025 952435308 73133171 62595819 36...
result:
ok 100 lines
Test #5:
score: 0
Wrong Answer
time: 1ms
memory: 4548kb
input:
1000 5 10 230 1 368 1 815 1 540 3 496 4 860 4 892 1 183 2 175 2 704 1 100 365 1 79 5 154 1 775 4 451 2 382 2 641 2 509 2 613 4 629 2 24 3 628 4 438 2 894 5 386 3 588 5 742 2 700 2 470 5 333 4 347 3 824 2 98 2 946 4 359 4 199 3 903 1 13 2 545 4 718 5 158 3 462 5 15 3 138 5 101 3 525 5 394 2 282 3 566...
output:
463261766 275273237 831504210 365936306 397215820 589348249 392409446 41855339 25502638 171851974 917028788 305678703 499792087 300379746 443583785 564892164 263901255 154095930 656303264 501915368 707553427 631324575 20682084 291944967 566920677 377568488 341896822 221671806 913617476 297926423 901...
result:
wrong answer 1st lines differ - expected: '255313133', found: '463261766'
Test #6:
score: 0
Wrong Answer
time: 2ms
memory: 4540kb
input:
1000 6 10 459 1 653 6 840 4 256 3 298 1 841 2 749 1 30 5 155 2 534 5 100 703 1 169 2 577 3 818 1 784 5 520 3 106 5 52 4 38 1 533 1 729 4 88 4 586 5 828 6 547 1 194 2 74 4 448 3 673 6 778 1 180 3 612 1 814 6 784 6 658 3 969 3 350 5 606 2 257 1 753 3 309 4 480 4 355 4 33 2 47 4 195 3 282 4 867 5 226 4...
output:
377095066 390544506 172348679 282060410 839030793 106063208 938189020 293412731 942344438 75677561 781909640 526177244 905845404 312206005 976772776 181042690 675267679 112910853 589869720 809869141 627406616 18768196 504948590 730697814 268485931 156166669 141756655 925551559 784852600 356203388 22...
result:
wrong answer 1st lines differ - expected: '999278415', found: '377095066'
Test #7:
score: 0
Wrong Answer
time: 15ms
memory: 4628kb
input:
1000 6 10 322 5 8 2 165 5 590 3 823 6 171 1 987 1 130 2 474 3 838 5 10000 854 4 329 1 324 2 361 4 479 4 657 6 27 1 121 3 57 5 790 4 81 1 246 3 720 5 917 4 430 6 506 3 129 3 752 2 119 6 382 1 146 4 233 3 420 5 20 1 413 5 925 5 466 4 682 5 632 4 128 4 574 1 503 4 543 1 274 3 273 5 742 2 399 4 36 3 237...
output:
61340827 530271231 608440927 996924295 316627686 141872936 785280222 258875612 180600160 858160957 353550317 600187027 409576581 491210419 8796346 409563456 283947745 909853410 588525272 462922593 296141271 820031819 225848573 361470370 843074693 522423857 644207712 312090489 986286036 768634405 791...
result:
wrong answer 1st lines differ - expected: '595188785', found: '61340827'
Test #8:
score: 0
Wrong Answer
time: 15ms
memory: 4376kb
input:
1000 6 10 454 6 42 2 861 3 46 2 592 2 220 1 641 1 415 4 687 3 803 5 10000 646 2 362 3 870 5 523 5 589 4 984 1 981 1 361 4 496 5 584 2 271 1 707 1 111 5 714 3 855 4 793 5 943 2 459 2 422 2 194 6 404 6 786 3 12 5 33 6 628 3 199 1 87 2 882 4 207 2 890 5 121 5 769 2 611 2 398 5 869 6 479 6 926 1 952 4 3...
output:
926271469 860072020 962222220 949048756 616421605 368142510 107210063 441445212 603978911 568725453 864085148 548142141 765711389 734161800 924031139 919249713 90062639 629558934 358661576 295327140 386871975 39576117 601758963 469403729 69320702 428401428 754125096 87997345 555991392 178536065 2599...
result:
wrong answer 1st lines differ - expected: '907977256', found: '926271469'
Test #9:
score: 0
Wrong Answer
time: 11ms
memory: 4456kb
input:
1000 6 10 855 4 342 2 897 3 652 6 279 2 715 3 439 1 582 6 711 1 249 3 10000 581 2 907 2 221 6 92 2 355 3 342 2 130 5 820 6 90 2 802 1 803 1 87 3 170 5 553 4 432 2 891 1 523 2 519 4 174 6 933 6 796 3 691 6 982 5 871 1 430 6 230 2 133 6 271 4 442 6 268 6 452 5 656 2 502 3 14 3 248 2 470 2 710 5 954 5 ...
output:
118458962 896356476 744283324 571601532 638030374 0 578593241 579338740 462943261 621283870 589572311 57420763 345453188 88265494 157601599 11735275 443948078 913358335 12861864 685013025 700887687 207237154 354392899 576338409 738175075 182092582 735846959 439328949 608403236 442784039 353689888 97...
result:
wrong answer 1st lines differ - expected: '55066393', found: '118458962'
Test #10:
score: 0
Wrong Answer
time: 15ms
memory: 4696kb
input:
1000 6 10 959 3 380 5 181 5 388 6 749 5 342 5 944 1 918 3 870 1 753 4 10000 383 4 321 3 646 1 893 4 776 3 664 2 518 5 234 1 114 6 639 1 764 1 207 1 877 3 273 5 764 1 799 5 385 6 314 3 982 6 784 6 819 5 83 6 651 4 221 3 355 1 829 4 144 6 862 3 786 2 385 6 857 4 53 4 55 4 710 4 186 2 735 2 878 3 955 5...
output:
769367875 993616476 359281807 781494199 347209174 179244692 333316583 159222879 690754560 4798207 178764220 416029490 815066875 323617492 178764220 517154593 642277356 223681406 960193437 165363105 979376589 183206306 72314938 686275963 420130723 781601134 729122841 244986860 782013683 642277356 267...
result:
wrong answer 1st lines differ - expected: '933292809', found: '769367875'