QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#432626 | #8782. Schoolgirls | ucup-team087# | WA | 5ms | 4040kb | C++20 | 27.4kb | 2024-06-07 14:22:52 | 2024-06-07 14:22:53 |
Judging History
answer
#line 1 "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 u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;
template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
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;
}
#endif
#line 1 "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__, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, 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()
#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 3 "main.cpp"
#line 2 "library/mod/mongomery_modint.hpp"
// odd mod.
// x の代わりに rx を持つ
template <int id, typename U1, typename U2>
struct Mongomery_modint {
using mint = Mongomery_modint;
inline static U1 m, r, n2;
static constexpr int W = numeric_limits<U1>::digits;
static void set_mod(U1 mod) {
assert(mod & 1 && mod <= U1(1) << (W - 2));
m = mod, n2 = -U2(m) % m, r = m;
FOR(5) r *= 2 - m * r;
r = -r;
assert(r * m == U1(-1));
}
static U1 reduce(U2 b) { return (b + U2(U1(b) * r) * m) >> W; }
U1 x;
Mongomery_modint() : x(0) {}
Mongomery_modint(U1 x) : x(reduce(U2(x) * n2)){};
U1 val() const {
U1 y = reduce(x);
return y >= m ? y - m : y;
}
mint &operator+=(mint y) {
x = ((x += y.x) >= m ? x - m : x);
return *this;
}
mint &operator-=(mint y) {
x -= (x >= y.x ? y.x : y.x - m);
return *this;
}
mint &operator*=(mint y) {
x = reduce(U2(x) * y.x);
return *this;
}
mint operator+(mint y) const { return mint(*this) += y; }
mint operator-(mint y) const { return mint(*this) -= y; }
mint operator*(mint y) const { return mint(*this) *= y; }
bool operator==(mint y) const {
return (x >= m ? x - m : x) == (y.x >= m ? y.x - m : y.x);
}
bool operator!=(mint y) const { return not operator==(y); }
mint pow(ll n) const {
assert(n >= 0);
mint y = 1, z = *this;
for (; n; n >>= 1, z *= z)
if (n & 1) y *= z;
return y;
}
};
template <int id>
using Mongomery_modint_32 = Mongomery_modint<id, u32, u64>;
template <int id>
using Mongomery_modint_64 = Mongomery_modint<id, u64, u128>;
#line 3 "library/nt/primetest.hpp"
bool primetest(const u64 x) {
assert(x < u64(1) << 62);
if (x == 2 or x == 3 or x == 5 or x == 7) return true;
if (x % 2 == 0 or x % 3 == 0 or x % 5 == 0 or x % 7 == 0) return false;
if (x < 121) return x > 1;
const u64 d = (x - 1) >> lowbit(x - 1);
using mint = Mongomery_modint_64<202311020>;
mint::set_mod(x);
const mint one(u64(1)), minus_one(x - 1);
auto ok = [&](u64 a) -> bool {
auto y = mint(a).pow(d);
u64 t = d;
while (y != one && y != minus_one && t != x - 1) y *= y, t <<= 1;
if (y != minus_one && t % 2 == 0) return false;
return true;
};
if (x < (u64(1) << 32)) {
for (u64 a: {2, 7, 61})
if (!ok(a)) return false;
} else {
for (u64 a: {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
if (!ok(a)) return false;
}
}
return true;
}
#line 2 "library/mod/dynamic_modint_64.hpp"
#line 2 "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 2 "library/mod/barrett.hpp"
// https://github.com/atcoder/ac-library/blob/master/atcoder/internal_math.hpp
struct Barrett {
u32 m;
u64 im;
explicit Barrett(u32 m = 1) : m(m), im(u64(-1) / m + 1) {}
u32 umod() const { return m; }
u32 modulo(u64 z) {
if (m == 1) return 0;
u64 x = (u64)(((unsigned __int128)(z)*im) >> 64);
u64 y = x * m;
return (z - y + (z < y ? m : 0));
}
u64 floor(u64 z) {
if (m == 1) return z;
u64 x = (u64)(((unsigned __int128)(z)*im) >> 64);
u64 y = x * m;
return (z < y ? x - 1 : x);
}
pair<u64, u32> divmod(u64 z) {
if (m == 1) return {z, 0};
u64 x = (u64)(((unsigned __int128)(z)*im) >> 64);
u64 y = x * m;
if (z < y) return {x - 1, z - y + m};
return {x, z - y};
}
u32 mul(u32 a, u32 b) { return modulo(u64(a) * b); }
};
struct Barrett_64 {
u128 mod, mh, ml;
explicit Barrett_64(u64 mod = 1) : mod(mod) {
u128 m = u128(-1) / mod;
if (m * mod + mod == u128(0)) ++m;
mh = m >> 64;
ml = m & u64(-1);
}
u64 umod() const { return mod; }
u64 modulo(u128 x) {
u128 z = (x & u64(-1)) * ml;
z = (x & u64(-1)) * mh + (x >> 64) * ml + (z >> 64);
z = (x >> 64) * mh + (z >> 64);
x -= z * mod;
return x < mod ? x : x - mod;
}
u64 mul(u64 a, u64 b) { return modulo(u128(a) * b); }
};
#line 5 "library/mod/dynamic_modint_64.hpp"
// https://codeforces.com/contest/453/problem/D
template <int id>
struct Dynamic_Modint_64 {
static constexpr bool is_modint = true;
using mint = Dynamic_Modint_64;
u64 val;
static Barrett_64 bt;
static u64 umod() { return bt.umod(); }
static ll get_mod() { return (ll)(bt.umod()); }
static void set_mod(ll m) {
assert(1 <= m);
bt = Barrett_64(m);
}
Dynamic_Modint_64() : val(0) {}
Dynamic_Modint_64(u64 x) : val(bt.modulo(x)) {}
Dynamic_Modint_64(u128 x) : val(bt.modulo(x)) {}
Dynamic_Modint_64(int x) : val((x %= get_mod()) < 0 ? x + get_mod() : x) {}
Dynamic_Modint_64(ll x) : val((x %= get_mod()) < 0 ? x + get_mod() : x) {}
Dynamic_Modint_64(i128 x) : val((x %= get_mod()) < 0 ? x + get_mod() : x) {}
mint& operator+=(const mint& rhs) {
val = (val += rhs.val) < umod() ? val : val - umod();
return *this;
}
mint& operator-=(const mint& rhs) {
val = (val += umod() - rhs.val) < umod() ? val : val - umod();
return *this;
}
mint& operator*=(const mint& rhs) {
val = bt.mul(val, rhs.val);
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inverse(); }
mint operator-() const { return mint() - *this; }
mint pow(ll n) const {
assert(0 <= n);
mint x = *this, r = u64(1);
while (n) {
if (n & 1) r *= x;
x *= x, n >>= 1;
}
return r;
}
mint inverse() const {
ll x = val, mod = get_mod();
ll a = x, b = mod, u = 1, v = 0, t;
while (b > 0) {
t = a / b;
swap(a -= t * b, b), swap(u -= t * v, v);
}
if (u < 0) u += mod;
return u64(u);
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs.val == rhs.val;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs.val != rhs.val;
}
};
#ifdef FASTIO
template <int id>
void rd(Dynamic_Modint_64<id>& x) {
fastio::rd(x.val);
assert(0 <= x.val && x.val < Dynamic_Modint_64<id>::get_mod());
}
template <int id>
void wt(Dynamic_Modint_64<id> x) {
fastio::wt(x.val);
}
#endif
using dmint64 = Dynamic_Modint_64<-1>;
template <int id>
Barrett_64 Dynamic_Modint_64<id>::bt;
#line 2 "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 "library/mod/primitive_root.hpp"
#line 2 "library/nt/factor.hpp"
#line 5 "library/nt/factor.hpp"
template <typename mint>
ll rho(ll n, ll c) {
assert(n > 1);
const mint cc(c);
auto f = [&](mint x) { return x * x + cc; };
mint x = 1, y = 2, z = 1, q = 1;
ll g = 1;
const ll m = 1LL << (__lg(n) / 5);
for (ll r = 1; g == 1; r <<= 1) {
x = y;
FOR(r) y = f(y);
for (ll k = 0; k < r && g == 1; k += m) {
z = y;
FOR(min(m, r - k)) y = f(y), q *= x - y;
g = gcd(q.val(), n);
}
}
if (g == n) do {
z = f(z);
g = gcd((x - z).val(), n);
} while (g == 1);
return g;
}
ll find_prime_factor(ll n) {
assert(n > 1);
if (primetest(n)) return n;
FOR(100) {
ll m = 0;
if (n < (1 << 30)) {
using mint = Mongomery_modint_32<20231025>;
mint::set_mod(n);
m = rho<mint>(n, RNG(0, n));
} else {
using mint = Mongomery_modint_64<20231025>;
mint::set_mod(n);
m = rho<mint>(n, RNG(0, n));
}
if (primetest(m)) return m;
n = m;
}
assert(0);
return -1;
}
// ソートしてくれる
vc<pair<ll, int>> factor(ll n) {
assert(n >= 1);
vc<pair<ll, int>> pf;
FOR(p, 2, 100) {
if (p * p > n) break;
if (n % p == 0) {
ll e = 0;
do { n /= p, e += 1; } while (n % p == 0);
pf.eb(p, e);
}
}
while (n > 1) {
ll p = find_prime_factor(n);
ll e = 0;
do { n /= p, e += 1; } while (n % p == 0);
pf.eb(p, e);
}
sort(all(pf));
return pf;
}
vc<pair<ll, int>> factor_by_lpf(ll n, vc<int>& lpf) {
vc<pair<ll, int>> res;
while (n > 1) {
int p = lpf[n];
int e = 0;
while (n % p == 0) {
n /= p;
++e;
}
res.eb(p, e);
}
return res;
}
#line 2 "library/mod/mod_pow.hpp"
#line 5 "library/mod/mod_pow.hpp"
u32 mod_pow(int a, ll n, int mod) {
assert(n >= 0);
a = ((a %= mod) < 0 ? a + mod : a);
if ((mod & 1) && (mod < (1 << 30))) {
using mint = Mongomery_modint_32<202311021>;
mint::set_mod(mod);
return mint(a).pow(n).val();
}
Barrett bt(mod);
int r = 1;
while (n) {
if (n & 1) r = bt.mul(r, a);
a = bt.mul(a, a), n >>= 1;
}
return r;
}
u64 mod_pow_64(ll a, ll n, u64 mod) {
assert(n >= 0);
a = ((a %= mod) < 0 ? a + mod : a);
if ((mod & 1) && (mod < (u64(1) << 62))) {
using mint = Mongomery_modint_64<202311021>;
mint::set_mod(mod);
return mint(a).pow(n).val();
}
Barrett_64 bt(mod);
ll r = 1;
while (n) {
if (n & 1) r = bt.mul(r, a);
a = bt.mul(a, a), n >>= 1;
}
return r;
}
#line 6 "library/mod/primitive_root.hpp"
// int
int primitive_root(int p) {
auto pf = factor(p - 1);
auto is_ok = [&](int g) -> bool {
for (auto&& [q, e]: pf)
if (mod_pow(g, (p - 1) / q, p) == 1) return false;
return true;
};
while (1) {
int x = RNG(1, p);
if (is_ok(x)) return x;
}
return -1;
}
ll primitive_root_64(ll p) {
auto pf = factor(p - 1);
auto is_ok = [&](ll g) -> bool {
for (auto&& [q, e]: pf)
if (mod_pow_64(g, (p - 1) / q, p) == 1) return false;
return true;
};
while (1) {
ll x = RNG(1, p);
if (is_ok(x)) return x;
}
return -1;
}
#line 8 "main.cpp"
using mint = Dynamic_Modint_64<0>;
void solve() {
LL(N, M, Q);
vc<tuple<int, int, int>> point;
FOR(M) {
INT(a, b, c);
point.eb(--a, --b, --c);
}
vvc<int> query;
FOR(Q) {
INT(n);
VEC(int, A, n);
for (auto& x: A) --x;
query.eb(A);
}
vc<ll> primes;
{
// p=2Nk+1 <= 2^60
ll max_k = ((1LL << 60) - 1) / (2 * N);
while (len(primes) < 40) {
ll k = RNG(1, max_k);
ll p = 2 * N * k + 1;
if (!primetest(p)) continue;
primes.eb(p);
break;
}
}
vc<int> ANS(Q, 1);
for (auto& p: primes) {
mint::set_mod(p);
// 1 の 2N 乗根
mint r = primitive_root_64(p);
mint z = r.pow((p - 1) / (2 * N)); // 2N 乗根
vc<mint> A(N);
FOR(i, N) { A[i] = z.pow(2 * i); }
FOR(i, M) {
auto [a, b, c] = point[i];
A.eb(A[a] + A[c] - A[b]);
}
FOR(q, Q) {
vc<int> I = query[q];
ll n = len(I);
if ((p - 1) % n != 0) {
ANS[q] = 0;
continue;
}
mint sm = 0;
for (auto& i: I) sm += A[i];
sm /= mint(n);
vc<mint> X;
for (auto& i: I) X.eb(A[i] - sm);
assert(SUM<mint>(X) == mint(0));
mint zz = r.pow((p - 1) / n);
mint x = X[0];
vc<mint> Y;
FOR(n) {
Y.eb(x);
x *= zz;
}
vc<u64> X64, Y64;
for (auto& x: X) X64.eb(x.val);
for (auto& x: Y) Y64.eb(x.val);
sort(all(X64));
sort(all(Y64));
if (X64 != Y64) ANS[q] = 0;
}
}
for (auto& x: ANS) Yes(x);
}
signed main() {
solve();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3992kb
input:
3 6 8 1 2 3 3 1 4 5 4 3 3 1 2 4 5 3 4 5 2 6 4 7 6 5 1 2 3 1 3 2 3 1 1 8 4 2 5 6 7 3 2 1 4 3 6 5 9 3 4 7 9 4 1 3 2 8
output:
Yes Yes Yes No No No Yes No
result:
ok 8 token(s): yes count is 4, no count is 4
Test #2:
score: 0
Accepted
time: 0ms
memory: 4000kb
input:
12 0 1 12 12 11 10 9 8 7 6 5 4 3 2 1
output:
Yes
result:
ok YES
Test #3:
score: -100
Wrong Answer
time: 5ms
memory: 4040kb
input:
3 0 6685 5 1 3 1 2 2 3 1 2 3 5 3 1 3 3 1 4 1 1 1 3 3 3 2 1 5 2 3 2 1 3 6 2 2 3 2 3 1 5 3 1 2 3 2 3 3 3 2 5 3 2 2 2 3 5 2 2 3 3 1 6 3 3 1 3 1 3 6 2 3 3 2 2 1 5 2 2 3 2 2 6 2 3 3 2 1 3 6 2 2 2 2 1 3 3 3 1 2 4 3 2 1 1 5 3 1 3 2 3 4 3 1 1 2 4 2 2 2 3 3 1 2 2 4 2 3 3 1 3 2 2 2 4 1 2 2 3 3 3 3 3 4 1 3 1 3...
output:
No Yes No No Yes No No No No No No No No No No No Yes No No No No No No Yes No Yes No No No No No No No No No No No No Yes No No No No No No No No Yes No No No No No Yes No Yes No No No No No No No No No No No No No No No No No No No No No Yes No No No No No No No No No No No No Yes No No No No No N...
result:
wrong answer expected YES, found NO [1129th token]