diff --git a/src/bin/.nvim.lua b/src/bin/.nvim.lua index 3783e19..a297068 100644 --- a/src/bin/.nvim.lua +++ b/src/bin/.nvim.lua @@ -75,10 +75,10 @@ local function add_timestamp() vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) end -vim.api.nvim_create_autocmd( - "BufWritePre", - { - pattern = "*.cc", - callback = add_timestamp, - } -) +-- vim.api.nvim_create_autocmd( +-- "BufWritePre", +-- { +-- pattern = "*.cc", +-- callback = add_timestamp, +-- } +-- ) diff --git a/src/bin/a.cc b/src/bin/a.cc index 7834781..a89e47a 100644 --- a/src/bin/a.cc +++ b/src/bin/a.cc @@ -1,16 +1,15 @@ /** * Author: subcrip - * Created: 2024-05-27 20:22:28 - * Modified: 2024-05-27 20:23:19 - * Elapsed: 0 minutes + * Created: 2024-06-03 22:38:12 + * Modified: 2024-06-03 22:39:28 + * Elapsed: 1 minutes */ #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -181,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -270,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -391,12 +402,12 @@ template struct MLL { struct MLLd { ll val, mdl; MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} - MLLd(const MLLd& other) : val(other.val) {} - friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val + rhs.val, lhs.mdl); } - friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - rhs.val, lhs.mdl); } - friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * rhs.val, lhs.mdl); } - friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl); } - friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - (lhs / rhs).val, lhs.mdl); } + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } @@ -425,6 +436,9 @@ istream& operator>>(istream& in, MLLd& num) { } // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } @@ -484,18 +498,23 @@ void prep() { void solve() { read(int, n, m); - if ((n + m) % 2 == 0 and n >= m) { - cout << "Yes\n"; - } else { - cout << "No\n"; + read(string, s); + array cnt = {}; + for (auto&& x : s) { + cnt[x - 'A'] += 1; } + int res = 0; + for (int i = 0; i < 7; ++i) { + res += max(0, m - cnt[i]); + } + cout << res << '\n'; } int main() { -#if __cplusplus < 201703L or defined(_MSC_VER) and not defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); diff --git a/src/bin/a.out b/src/bin/a.out index 8114a4e..f36b593 100755 Binary files a/src/bin/a.out and b/src/bin/a.out differ diff --git a/src/bin/b.cc b/src/bin/b.cc index 86d9d01..a9b20b8 100644 --- a/src/bin/b.cc +++ b/src/bin/b.cc @@ -1,16 +1,15 @@ /** * Author: subcrip - * Created: 2024-05-27 20:25:18 - * Modified: 2024-05-27 20:30:47 + * Created: 2024-06-03 22:41:03 + * Modified: 2024-06-03 22:46:36 * Elapsed: 5 minutes */ #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -181,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -270,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -391,12 +402,12 @@ template struct MLL { struct MLLd { ll val, mdl; MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} - MLLd(const MLLd& other) : val(other.val) {} - friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val + rhs.val, lhs.mdl); } - friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - rhs.val, lhs.mdl); } - friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * rhs.val, lhs.mdl); } - friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl); } - friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - (lhs / rhs).val, lhs.mdl); } + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } @@ -425,6 +436,9 @@ istream& operator>>(istream& in, MLLd& num) { } // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } @@ -483,31 +497,27 @@ void prep() { } void solve() { - read(int, x); - vector res; - int prev = 0; - for (int i = 0; i <= 31; ++i) { - int curr = x >> i & 1; - int carry = 0; - if (curr + prev == 1 and res.size() and res.back() == 1) { - carry = 1; - res.back() = -1; - res.emplace_back(0); - } else { - carry = (curr + prev) / 2; - res.emplace_back((curr + prev) % 2); - } - prev = carry; + read(int, n, f, k); + readvec(int,a ,n); + f = a[f - 1]; + sort(a.begin(), a.end(), greater()); + int yes = 0, no = 0; + if (a[k - 1] > f) { + cout << "NO\n"; + } else if (a[k - 1] < f) { + cout << "YES\n"; + } else if (k <= n - 1 and a[k] == f) { + cout << "MAYBE\n"; + } else { + cout << "YES\n"; } - cout << res.size() << '\n'; - putvec(res); } int main() { -#if __cplusplus < 201703L or defined(_MSC_VER) and not defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); diff --git a/src/bin/c.cc b/src/bin/c.cc index 278b7db..8bdcc68 100644 --- a/src/bin/c.cc +++ b/src/bin/c.cc @@ -1,16 +1,15 @@ /** * Author: subcrip - * Created: 2024-05-27 20:38:48 - * Modified: 2024-05-27 20:46:39 - * Elapsed: 7 minutes + * Created: 2024-06-03 22:48:29 + * Modified: 2024-06-03 23:01:57 + * Elapsed: 13 minutes */ #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -181,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -270,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -391,12 +402,12 @@ template struct MLL { struct MLLd { ll val, mdl; MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} - MLLd(const MLLd& other) : val(other.val) {} - friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val + rhs.val, lhs.mdl); } - friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - rhs.val, lhs.mdl); } - friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * rhs.val, lhs.mdl); } - friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl); } - friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return mod(lhs.val - (lhs / rhs).val, lhs.mdl); } + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } @@ -425,6 +436,9 @@ istream& operator>>(istream& in, MLLd& num) { } // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } @@ -485,55 +499,43 @@ void prep() { void solve() { read(int, n); readvec(int, a, n); - sort(a.begin(), a.end()); - int f = 1; - for (int i = 0; i < n - 1; ++i) { - if (a[n - 1] % a[i] != 0) { - f = 0; - break; + readvec(int, b, n); + read(int, m); + unordered_map, safe_hash> cnt; + vector c(m); + unordered_set oc(b.begin(), b.end()); + for (int i = 0; i < m; ++i) { + read(int, x); + c[i] = x; + cnt[x].emplace_back(i); + } + vector res(m); + for (int i = 0; i < n; ++i) { + if (a[i] != b[i]) { + if (cnt[b[i]].empty()) { + cout << "NO\n"; + return; + } + cnt[b[i]].pop_back(); } } - if (not f) { - cout << n << '\n'; - } else { - int sq = sqrt(a[n - 1]); - set st; - for (int i = 1; i <= sq; ++i) { - if (a[n - 1] % i == 0) { - st.emplace(i); - st.emplace(a[n - 1] / i); - } + int f = 0; + for (int i = m - 1; ~i; --i) { + if (oc.count(c[i])) { + f = 1; + } else if (f == 0) { + cout << "NO\n"; + return; } - int N = 0; - unordered_map mp, rev; - for (auto&& x : st) mp[x] = ++N, rev[N] = x; - vector> dp(n + 1, vector(N + 1)); - for (int i = 1; i <= n; ++i) { - for (int j = 1; j <= N; ++j) { - dp[i][j] = dp[i - 1][j]; - } - for (int j = 1; j <= N; ++j) { - if (dp[i - 1][j] != 0) - dp[i][mp[lcm(a[i - 1], rev[j])]] = max(dp[i][mp[lcm(a[i - 1], rev[j])]], dp[i - 1][j] + 1); - } - dp[i][mp[a[i - 1]]] = max(dp[i][mp[a[i - 1]]], 1); - } - unordered_set nums(a.begin(), a.end()); - int res = 0; - for (int j = 1; j <= N; ++j) { - if (not nums.count(rev[j])) { - res = max(res, dp[n][j]); - } - } - cout << res << '\n'; } + cout << "YES\n"; } int main() { -#if __cplusplus < 201703L or defined(_MSC_VER) and not defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); diff --git a/src/bin/cf-1615d.cc b/src/bin/cf-1615d.cc new file mode 100644 index 0000000..db0cfcd --- /dev/null +++ b/src/bin/cf-1615d.cc @@ -0,0 +1,727 @@ +/** + * Author: subcrip + * Created: 2024-06-05 12:44:48 + * Modified: 2024-06-05 13:39:50 + * Elapsed: 55 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +namespace tarjan { + struct mutex_cond { + int v1; bool cond1; + int v2; bool cond2; + mutex_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {} + }; + struct inclusive_cond { + int v1; bool cond1; + int v2; bool cond2; + inclusive_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {} + }; + // Returns the mapping between vertices and their affiliated sccs. + vector scc(const vector>& ch) { + int n = ch.size(); + int cnt = 0, scn = 0; + vector dfn(n), low(n), vis(n), st; + vector br(n); + auto tarjan = [&] (auto tarjan, int v) -> void { + dfn[v]=low[v]=++cnt; + st.push_back(v); + vis[v]=1; + for(const auto&u:ch[v]) + if(!dfn[u]) tarjan(tarjan, u),low[v]=min(low[v],low[u]); + else if(vis[u])low[v]=min(low[v],dfn[u]); + if(dfn[v]==low[v]){ + ++scn; + int u; + do u=st.back(), st.pop_back(),vis[u]=0,br[u]=scn; while(u!=v); + } + }; + for (int i = 0; i < n; ++i) { + if (!dfn[i]) { + tarjan(tarjan, i); + } + } + return br; + } + // This method can eliminate redundant edges or self-loops + vector> build_scc(const vector>& ch) { + int n = ch.size(); + auto br = scc(ch); + int cnt = *max_element(br.begin(), br.end()); + vector> rb(cnt + 1); + for (int i = 0; i < n; ++i) { + for (auto&& u : ch[i]) { + if (br[i] != br[u]) rb[br[i]].emplace(br[u]); + } + } + vector> res(cnt + 1); + for (int i = 1; i <= cnt; ++i) { + res[i] = vector(rb[i].begin(), rb[i].end()); + } + return res; + } + + // This method can eliminate redundant edges or self-loops + // return form: (scc size, children of scc) + vector>> build_scc_with_size(const vector>& ch) { + int n = ch.size(); + auto br = scc(ch); + int cnt = *max_element(br.begin(), br.end()); + vector> rb(cnt + 1); + for (int i = 0; i < n; ++i) { + for (auto&& u : ch[i]) { + if (br[i] != br[u]) rb[br[i]].emplace(br[u]); + } + } + vector>> res(cnt + 1); + for (int i = 1; i <= cnt; ++i) { + res[i].second = vector(rb[i].begin(), rb[i].end()); + } + for (int i = 1; i <= n; ++i) { + res[br[i]].first += 1; + } + return res; + } + // indices start from 1, result has `n` items + optional> solve_twosat(int n, const vector& conditions) { + vector> ch(2 * n + 1); + for (auto&& [v1, cond1, v2, cond2] : conditions) { + ch[(1 ^ cond1) * n + v1].emplace_back(cond2 * n + v2); + ch[(1 ^ cond2) * n + v2].emplace_back(cond1 * n + v1); + } + auto sccno = scc(ch); + for (int i = 1; i <= n; ++i) { + if (sccno[i] == sccno[i + n]) { + return nullopt; + } + } + vector res; + for (int i = 1; i <= n; ++i) { + if (sccno[i] < sccno[i + n]) { + res.emplace_back(false); + } else { + res.emplace_back(true); + } + } + return res; + }; + // indices start from 1, result has `n` items + optional> solve_twosat(int n, const vector& conditions) { + vector trans_conds; + for (auto&& [v1, cond1, v2, cond2] : conditions) { + trans_conds.emplace_back(v1, cond1, v2, not cond2); + } + return solve_twosat(n, trans_conds); + } + // Returns if each vertex is a cut vertex + // All indices start from 1 + vector cut_v(const vector>& ch) { + int n = ch.size() - 1; + vector vis(n + 1); + vector low(n + 1), dfn(n + 1), flag(n + 1); + int cnt = 0; + auto dfs = [&] (auto dfs, int v, int pa) -> void { + vis[v] = 1; + low[v] = dfn[v] = ++cnt; + int child = 0; + for (auto&& u : ch[v]) { + if (not vis[u]) { + ++child; + dfs(dfs, u, v); + low[v] = min(low[v], low[u]); + if (pa != v and low[u] >= dfn[v] and not flag[v]) { + flag[v] = 1; + } + } else if (u != pa) { + low[v] = min(low[v], dfn[u]); + } + } + if (pa == v and child >= 2 and not flag[v]) { + flag[v] = 1; + } + }; + for (int i = 1; i <= n; ++i) { + if (not dfn[i]) { + dfs(dfs, i, 0); + } + } + return flag; + } +} + +void solve() { + read(int, n, m); + vector> e(n + 1); + vector conditions; + auto insert = [&] (int u, int v, bool w) -> void { + if (w == 1) { + conditions.push_back({ + u, 1, + v, 1, + }); + conditions.push_back({ + u, 0, + v, 0, + }); + } else { + conditions.push_back({ + u, 1, + v, 0, + }); + conditions.push_back({ + u, 0, + v, 1, + }); + } + }; + vector res(n - 1, -1); + vector edges(n - 1); + for (int i = 0; i < n - 1; ++i) { + read(int, u, v, w); + edgew(e, u, v, i); + edges[i] = {u, v}; + if (w != -1) { + insert(u, v, parity(w)); + res[i] = w; + } + } + while (m--) { + read(int, u, v, w); + insert(u, v, w); + } + auto sol = tarjan::solve_twosat(n, conditions); + if (sol == nullopt) { + cout << "NO\n"; + } else { + cout << "YES\n"; + auto dfs = [&] (auto dfs, int v, int pa) -> void { + for (auto&& [u, id] : e[v]) { + if (u == pa) continue; + if (res[id] == -1) { + res[id] = (*sol)[u - 1] ^ (*sol)[v - 1]; + } + dfs(dfs, u, v); + } + }; + dfs(dfs, 1, 0); + for (int i = 0; i < n - 1; ++i) { + cout << edges[i].first << ' ' << edges[i].second << ' ' << res[i] << '\n'; + } + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1617d2.cc b/src/bin/cf-1617d2.cc new file mode 100644 index 0000000..91b320f --- /dev/null +++ b/src/bin/cf-1617d2.cc @@ -0,0 +1,609 @@ +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +bool query(int i, int j, int k) { + cout << "? " << i + 1 << ' ' << j + 1 << ' ' << k + 1 << endl; + read(int, x); + if (x == -1) exit(0); + return x ^ 1; +} + +void claim(const vector& idx) { + cout << "! " << idx.size(); + for (auto&& x : idx) cout << ' ' << x + 1; + cout << endl; +} + +void solve() { + read(int, n); + int m = n / 3; + vector dense(m); + vector is_impostor(n); + int p = -1, q = -1; + for (int i = 0; i < m; ++i) { + dense[i] = query(i * 3, i * 3 + 1, i * 3 + 2); + if (dense[i]) p = i; + else q = i; + } + assert(p != -1 and q != -1); + int zero = -1, one = -1; + if (query(3 * p, 3 * p + 1, 3 * q) == 0 or + query(3 * p, 3 * p + 1, 3 * q + 1) == 0 or + query(3 * p, 3 * p + 1, 3 * q + 2) == 0) { + // one of them is 0, the remaining one must be 1. + one = 3 * p + 2; + } else { + // both of them is 1, set to an arbitrary one. + one = 3 * p; + } + if (query(3 * q, 3 * q + 1, one) == 0) { + zero = 3 * q; + } else if (query(3 * q, 3 * q + 2, one) == 0) { + zero = 3 * q; + } else { + zero = 3 * q + 1; + } + for (int i = 0; i < m; ++i) { + int curr = 0; + if (dense[i]) { + int left = query(3 * i, 3 * i + 1, zero); + int right = query(3 * i, 3 * i + 2, zero); + if (left == 0 and right == 0) { + is_impostor[3 * i] = 0; + is_impostor[3 * i + 1] = 1; + is_impostor[3 * i + 2] = 1; + } else if (left == 0 and right == 1) { + is_impostor[3 * i] = 1; + is_impostor[3 * i + 1] = 0; + is_impostor[3 * i + 2] = 1; + } else if (left == 1 and right == 0) { + is_impostor[3 * i] = 1; + is_impostor[3 * i + 1] = 1; + is_impostor[3 * i + 2] = 0; + } else { + is_impostor[3 * i] = 1; + is_impostor[3 * i + 1] = 1; + is_impostor[3 * i + 2] = 1; + } + } else { + int left = query(3 * i, 3 * i + 1, one); + int right = query(3 * i, 3 * i + 2, one); + if (left == 0 and right == 0) { + is_impostor[3 * i] = 0; + is_impostor[3 * i + 1] = 0; + is_impostor[3 * i + 2] = 0; + } else if (left == 0 and right == 1) { + is_impostor[3 * i] = 0; + is_impostor[3 * i + 1] = 0; + is_impostor[3 * i + 2] = 1; + } else if (left == 1 and right == 0) { + is_impostor[3 * i] = 0; + is_impostor[3 * i + 1] = 1; + is_impostor[3 * i + 2] = 0; + } else { + is_impostor[3 * i] = 1; + is_impostor[3 * i + 1] = 0; + is_impostor[3 * i + 2] = 0; + } + } + } + vector res; + for (int i = 0; i < n; ++i) { + if (is_impostor[i]) res.emplace_back(i); + } + claim(res); +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1619g.cc b/src/bin/cf-1619g.cc new file mode 100644 index 0000000..e22b24b --- /dev/null +++ b/src/bin/cf-1619g.cc @@ -0,0 +1,660 @@ +/** + * Author: subcrip + * Created: 2024-06-05 13:40:00 + * Modified: 2024-06-05 13:51:37 + * Elapsed: 11 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 23 +// #define TOT_TEST_CASE 10000 + +void dump() { + read(int, n, k); + cout << n << ' ' << k << '\n'; + for (int i = 0; i < n; ++i) { + read(int, x, y, t); + cout << x << ' ' << y << ' ' << t << '\n'; + } +} + +void dump_ignore() { + read(int, n, k); + for (int i = 0; i < n; ++i) { + read(int, x, y, t); + } +} + +void prep() { +} + +class quick_union { +public: + vector c, sz; +public: + quick_union(size_t n) : c(n), sz(n) { + iota(c.begin(), c.end(), 0); + sz.assign(n, 1); + } + + size_t query(size_t i) { + if (c[i] != i) c[i] = query(c[i]); + return c[i]; + } + + void merge(size_t i, size_t j) { + if (connected(i, j)) return; + sz[query(j)] += sz[query(i)]; + c[query(i)] = query(j); + } + bool connected(size_t i, size_t j) { + return query(i) == query(j); + } + size_t query_size(size_t i) { + return sz[query(i)]; + } +}; + +void solve() { + read(int, n, k); + unordered_map, safe_hash> row, col; + vector co(n); + map> rev; + for (int i = 0; i < n; ++i) { + read(int, x, y, t); + rev[t].emplace_back(i); + row[x].emplace_back(y, i); + col[y].emplace_back(x, i); + co[i] = { x, y }; + } + unordered_map, safe_hash> row_link, col_link; + vector::iterator, list::iterator>> pt(n); + vector stale(n); + for (auto&& [x, v] : row) { + sort(v.begin(), v.end()); + row_link[x].insert(row_link[x].end(), v.begin(), v.end()); + for (auto it = row_link[x].begin(); it != row_link[x].end(); ++it) { + pt[it->second].first = it; + } + } + for (auto&& [y, v] : col) { + sort(v.begin(), v.end()); + col_link[y].insert(col_link[y].end(), v.begin(), v.end()); + for (auto it = col_link[y].begin(); it != col_link[y].end(); ++it) { + pt[it->second].second = it; + } + } + quick_union qu(n); + auto dfs = [&] (auto dfs, int v) -> void { + auto [x, y] = co[v]; + auto [row_it, col_it] = pt[v]; + stale[v] = 1; + // down + if (row_it != row_link[x].begin()) { + auto prev_it = prev(row_it); + if (not stale[prev_it->second] and y - prev_it->first <= k) { + qu.merge(v, prev_it->second); + dfs(dfs, prev_it->second); + } + } + // up + if (row_it != row_link[x].end()) { + auto next_it = next(row_it); + if (next_it != row_link[x].end()) { + if (not stale[next_it->second] and next_it->first - y <= k) { + qu.merge(v, next_it->second); + dfs(dfs, next_it->second); + } + } + } + // left + if (col_it != col_link[y].begin()) { + auto prev_it = prev(col_it); + if (not stale[prev_it->second] and x - prev_it->first <= k) { + qu.merge(v, prev_it->second); + dfs(dfs, prev_it->second); + } + } + // right + if (col_it != col_link[x].end()) { + auto next_it = next(col_it); + if (next_it != col_link[y].end()) { + if (not stale[next_it->second] and next_it->first - x <= k) { + qu.merge(v, next_it->second); + dfs(dfs, next_it->second); + } + } + } + + row_link[x].erase(row_it); + col_link[y].erase(col_it); + }; + for (int i = 0; i < n; ++i) { + if (not stale[i]) { + dfs(dfs, i); + } + } + int blk = 0; + for (int i = 0; i < n; ++i) { + if (qu.query(i) == i) { + blk += 1; + } + } + vector use(n); + int res = blk - 1; + for (auto&& [t, v] : rev) { + for (auto&& i : v) { + if (use[qu.query(i)]) continue; + use[qu.query(i)] = 1; + blk -= 1; + } + res = min(res, t + max(0, blk - t - 1)); + } + cout << res << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1689d.cc b/src/bin/cf-1689d.cc new file mode 100644 index 0000000..3a1dbf6 --- /dev/null +++ b/src/bin/cf-1689d.cc @@ -0,0 +1,688 @@ +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template> class segtree { +private: + using size_type = uint64_t; + using info_type = Addable_Info_t; + using tag_type = Tag_t; + size_type _max; + vector d; + vector b; + void pull(size_type p) { + d[p] = d[p * 2] + d[p * 2 + 1]; + } + void push(size_type p, size_type left_len, size_type right_len) { + d[p * 2].apply(b[p], left_len), d[p * 2 + 1].apply(b[p], right_len); + b[p * 2].apply(b[p]), b[p * 2 + 1].apply(b[p]); + b[p] = tag_type(); + } + void set(size_type s, size_type t, size_type p, size_type x, const info_type& c) { + if (s == t) { + d[p] = c; + return; + } + size_type m = s + (t - s >> 1); + if (s != t) push(p, m - s + 1, t - m); + if (x <= m) set(s, m, p * 2, x, c); + else set(m + 1, t, p * 2 + 1, x, c); + pull(p); + } + + void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) { + if (l <= s && t <= r) { + d[p].apply(c, t - s + 1); + b[p].apply(c); + return; + } + size_type m = s + (t - s >> 1); + push(p, m - s + 1, t - m); + if (l <= m) range_apply(s, m, p * 2, l, r, c); + if (r > m) range_apply(m + 1, t, p * 2 + 1, l, r, c); + pull(p); + } + info_type range_query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (l <= s && t <= r) { + return d[p]; + } + size_type m = s + (t - s >> 1); + info_type res = {}; + push(p, m - s + 1, t - m); + if (l <= m) res = res + range_query(s, m, p * 2, l, r); + if (r > m) res = res + range_query(m + 1, t, p * 2 + 1, l, r); + return res; + } + void build(const Sequence& a, size_type s, size_type t, size_type p) { + if (s == t) { + d[p] = a[s]; + return; + } + int m = s + (t - s >> 1); + build(a, s, m, p * 2); + build(a, m + 1, t, p * 2 + 1); + pull(p); + } +public: + segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {} + segtree(const Sequence& a) : segtree(a.size()) { + build(a, {}, _max, 1); + } + void set(size_type i, const info_type& c) { + set({}, _max, 1, i, c); + } + + void range_apply(size_type l, size_type r, const tag_type& c) { + range_apply({}, _max, 1, l, r, c); + } + void apply(size_type i, const tag_type& c) { + range_apply(i, i, c); + } + info_type range_query(size_type l, size_type r) { + return range_query({}, _max, 1, l, r); + } + info_type query(size_type i) { + return range_query(i, i); + } + Sequence serialize() { + Sequence res = {}; + for (size_type i = 0; i <= _max; ++i) { + res.push_back(query(i)); + } + return res; + } + const vector& get_d() { + return d; + } +}; +struct Tag { + ll val = -INFLL; + void apply(const Tag& rhs) { + val = max(val, rhs.val); + } +}; +struct Info { + ll val = -INFLL; + void apply(const Tag& rhs, size_t len) { + val = max(val, rhs.val); + } +}; +Info operator+(const Info &a, const Info &b) { + return {max(a.val, b.val)}; +} + +void solve() { + read(int, n, m); + vector> row(n); + segtree big(m), small(m); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + read(char, c); + if (c == 'B') { + row[i].emplace_back(j); + } + } + } + vector> res(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (auto&& j : row[i]) { + big.apply(j, {-i+j}); + small.apply(j, {-i-j}); + } + for (int j = 0; j < m; ++j) { + ll big_query = big.range_query(j, m).val; + ll small_query = small.range_query(0, j).val; + if (big_query != -INFLL) { + res[i][j] = max(res[i][j], i - j + int(big_query)); + } + if (small_query != -INFLL) { + res[i][j] = max(res[i][j], i + j + int(small_query)); + } + } + } + for (int j = 0; j < m; ++j) { + big.set(j, {}); + small.set(j, {}); + } + for (int i = n - 1; ~i; --i) { + for (auto&& j : row[i]) { + big.apply(j, {i+j}); + small.apply(j, {i-j}); + } + for (int j = 0; j < m; ++j) { + ll big_query = big.range_query(j, m).val; + ll small_query = small.range_query(0, j).val; + if (big_query != -INFLL) { + res[i][j] = max(res[i][j], - i - j + int(big_query)); + } + if (small_query != -INFLL) { + res[i][j] = max(res[i][j], - i + j + int(small_query)); + } + } + } + int ans = INF; + int x = 0, y = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + if (res[i][j] < ans) { + ans = res[i][j]; + x = i + 1; + y = j + 1; + } + } + } + cout << x << ' ' << y << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1692h.cc b/src/bin/cf-1692h.cc new file mode 100644 index 0000000..0f14b76 --- /dev/null +++ b/src/bin/cf-1692h.cc @@ -0,0 +1,542 @@ +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(int, n); + readvec(int, a, n); + vector ps(n); + unordered_map, safe_hash> bk; + int choice = a[0], l = 0, r = 0; + int res = 1; + for (int i = 0; i < n; ++i) { + int curr = 2 * bk[a[i]].first - i; + if (bk[a[i]].first > 0) { + if (curr + 1 - ps[bk[a[i]].second] > res) { + res = curr + 1 - ps[bk[a[i]].second]; + choice = a[i]; + l = bk[a[i]].second; + r = i; + } + } + ps[i] = curr; + if (bk[a[i]].first == 0 or ps[i] < ps[bk[a[i]].second]) { + bk[a[i]].second = i; + } + bk[a[i]].first += 1; + } + cout << choice << ' ' << l + 1 << ' ' << r + 1 << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1693b.cc b/src/bin/cf-1693b.cc new file mode 100644 index 0000000..60294a5 --- /dev/null +++ b/src/bin/cf-1693b.cc @@ -0,0 +1,553 @@ +/** + * Author: subcrip + * Created: 2024-06-03 21:57:30 + * Modified: 2024-06-03 22:01:36 + * Elapsed: 4 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(int, n); + adj(ch, n); + for (int i = 2; i <= n; ++i) { + read(int, p); + edge(ch, i, p); + } + vector target(n + 1); + for (int i = 1; i <= n; ++i) { + cin >> target[i]; + } + int res = 0; + auto dfs = [&] (auto dfs, int v, int pa) -> ll { + ll sum = 0; + for (auto&& u : ch[v]) { + if (u == pa) continue; + sum += dfs(dfs, u, v); + } + if (sum >= target[v].second) { + sum = target[v].second; + } else if (sum < target[v].first) { + sum = target[v].second; + res += 1; + } + return sum; + }; + dfs(dfs, 1, 0); + cout << res << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1702f.cc b/src/bin/cf-1702f.cc new file mode 100644 index 0000000..0d8e741 --- /dev/null +++ b/src/bin/cf-1702f.cc @@ -0,0 +1,550 @@ +/** + * Author: subcrip + * Created: 2024-06-03 15:39:47 + * Modified: 2024-06-03 16:27:08 + * Elapsed: 47 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(int, n); + readvec(int, a, n); + readvec(int, b, n); + unordered_map bk; + for (int i = 0; i < n; ++i) { + bk[a[i] >> __builtin_ctz(a[i])] += 1; + } + for (int i = 0; i < n; ++i) { + while (b[i] != 0) { + b[i] >>= __builtin_ctz(b[i]); + if (bk.count(b[i])) { + if (--bk[b[i]] == 0) { + bk.erase(b[i]); + } + break; + } + b[i] >>= 1; + } + } + if (bk.size() == 0) { + cout << "YES\n"; + } else { + cout << "NO\n"; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1703g.cc b/src/bin/cf-1703g.cc new file mode 100644 index 0000000..6b9a172 --- /dev/null +++ b/src/bin/cf-1703g.cc @@ -0,0 +1,546 @@ +/** + * Author: subcrip + * Created: 2024-06-03 14:55:45 + * Modified: 2024-06-03 15:26:11 + * Elapsed: 30 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + constexpr ll m = lg2(MDL) + 2; + read(ll, n, k); + readvec(ll, a, n); + ll sum = accumulate(a.begin(), a.end(), ll(0)); + vector> ss(n + 1, vector(m)); + for (ll j = 1; j < m; ++j) { + for (ll i = n - 1; ~i; --i) { + ss[i][j] = ss[i + 1][j] + a[i] - a[i] / 2; + a[i] /= 2; + } + } + vector> dp(n + 1, vector(m, INFLL)); + dp[0][0] = 0; + for (ll i = 1; i <= n; ++i) { + dp[i][0] = dp[i - 1][0] + k; + for (ll j = 1; j < m; ++j) { + dp[i][j] = min(dp[i - 1][j] + k, dp[i - 1][j - 1] + ss[i - 1][j]); + } + } + cout << sum - *min_element(dp[n].begin(), dp[n].end()) << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1707b.cc b/src/bin/cf-1707b.cc new file mode 100644 index 0000000..9e82f16 --- /dev/null +++ b/src/bin/cf-1707b.cc @@ -0,0 +1,580 @@ +/** + * Author: subcrip + * Created: 2024-06-03 12:01:51 + * Modified: 2024-06-03 14:07:12 + * Elapsed: 125 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(int, n); + vector a, b; + int m = 0; + int prev = -1; + int zeros = 0; + int first = 0; + for (int i = 0; i < n; ++i) { + read(int, x); + if (x == 0) { + first = 1; + } + if (x != prev) { + if (prev == 0) first = 1; + a.emplace_back(x); + m += 1; + prev = x; + } else { + zeros += 1; + } + } + for (int i = 0; i < n - 1; ++i) { + int m = a.size(); + if (m <= 1) { + break; + } + // debug(a); + // debug(zeros); + set oc; + if (first) { + oc.emplace(a[0]); + } + if (zeros) { + first = 1; + zeros -= 1; + } else { + first = 0; + } + for (int i = 1; i < m; ++i) { + if (oc.count(a[i] - a[i - 1])) { + zeros += 1; + } else { + oc.emplace(a[i] - a[i - 1]); + } + } + a.clear(); + for (auto&& x : oc) { + a.emplace_back(x); + } + } + if (m == 0) { + cout << 0 << '\n'; + } else { + cout << a[0] << '\n'; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1709c.cc b/src/bin/cf-1709c.cc new file mode 100644 index 0000000..0d7a6ec --- /dev/null +++ b/src/bin/cf-1709c.cc @@ -0,0 +1,579 @@ +/** + * Author: subcrip + * Created: 2024-06-02 23:15:35 + * Modified: 2024-06-03 00:11:27 + * Elapsed: 55 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(string, a); + int n = a.size(); + int s = 0, cnt = 0; + for (int i = 0; i < n; ++i) { + if (a[i] == '(') { + s += 1; + } else if (a[i] == ')') { + s -= 1; + } else { + cnt += 1; + } + } + s = -s; + int x = cnt + s >> 1, y = cnt - s >> 1; + int curr = 0, cx = x, cy = y; + string p, q; + for (int i = 0; i < n; ++i) { + if (a[i] == '(') { + curr += 1; + } else if (a[i] == ')') { + curr -= 1; + } else { + if (cx) { + p += '('; + curr += 1; + cx -= 1; + } else { + p += ')'; + curr -= 1; + } + } + } + for (int i = 0; i < n; ++i) { + if (a[i] == '(') { + curr += 1; + } else if (a[i] == ')') { + curr -= 1; + } else { + if (curr > 0 and cy) { + q += ')'; + curr -= 1; + cy -= 1; + } else { + q += '('; + curr += 1; + } + } + } + if (p == q) { + cout << "YES\n"; + } else { + cout << "NO\n"; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1980d.cc b/src/bin/cf-1980d.cc new file mode 100644 index 0000000..be0a94f --- /dev/null +++ b/src/bin/cf-1980d.cc @@ -0,0 +1,556 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:04:55 + * Modified: 2024-06-04 20:27:56 + * Elapsed: 1283 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +void solve() { + read(int, n); + readvec(int, a, n); + auto check = [&] (int idx) -> bool { + int prev_num = idx == 0 ? a[1] : a[0]; + int prev_gcd = -INF; + for (int i = idx == 0 ? 2 : 1; i < n; ++i) { + if (i == idx) continue; + int curr_gcd = gcd(a[i], prev_num); + if (curr_gcd < prev_gcd) { + return false; + } + prev_gcd = curr_gcd; + prev_num = a[i]; + } + return true; + }; + int prev_gcd = -INF; + for (int i = 1; i < n; ++i) { + int curr_gcd = gcd(a[i], a[i - 1]); + if (curr_gcd < prev_gcd) { + if ((i - 2 >= 0 and check(i - 2)) or check(i - 1) or check(i)) { + cout << "YES\n"; + } else { + cout << "NO\n"; + } + return; + } + prev_gcd = curr_gcd; + } + cout << "YES\n"; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1980e.cc b/src/bin/cf-1980e.cc new file mode 100644 index 0000000..b7c2880 --- /dev/null +++ b/src/bin/cf-1980e.cc @@ -0,0 +1,663 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:18:29 + * Modified: 2024-06-04 20:28:04 + * Elapsed: 1269 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +static vector> power1; +static vector> power2; +static const ll b = rd(); +template +struct hash_vec { + using hash_type = pll; + MLL hash1; + MLL hash2; + vector<_Tp> seq; + size_t size() { + return seq.size(); + } + void push_back(const _Tp& x) { + hash1 = hash1 * b + x; + hash2 = hash2 * b + x; + seq.push_back(x); + } + void push_front(const _Tp& x) { + size_t length = size(); + hash1 += x * power1[length]; + hash2 += x * power2[length]; + seq.push_front(x); + } + void pop_back() { + _Tp e = seq.back(); seq.pop_back(); + hash1 = (hash1 - e) / b; + hash2 = (hash2 - e) / b; + } + void pop_front() { + _Tp e = seq.front(); seq.pop_front(); + int length = seq.size(); + hash1 -= e * power1[length]; + hash2 -= e * power2[length]; + } + void set(size_t pos, const _Tp& value) { + int length = seq.size(); + int old_value = seq[pos]; + hash1 += (value - old_value) * power1[length - 1 - pos]; + hash2 += (value - old_value) * power2[length - 1 - pos]; + seq[pos] = value; + } + const _Tp& operator[](size_t pos) { + return seq[pos]; + } + hash_type hash() { + return {hash1.val, hash2.val}; + } + void clear() { + hash1 = 0; + hash2 = 0; + seq.clear(); + } + hash_vec(size_t maxn) { + clear(); + MLL c1 = power1.size() ? power1.back() * b : 1; + MLL c2 = power2.size() ? power2.back() * b : 1; + for (int i = power1.size(); i < maxn; ++i) { + power1.push_back(c1); + power2.push_back(c2); + c1 *= b; + c2 *= b; + } + } + hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) { + for (size_t i = 0; i != maxn; ++i) { + push_back(init_value); + } + } +}; + +void solve() { + read(int, n, m); + vector> a(n, vector(m)), b(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> a[i][j]; + } + } + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> b[i][j]; + } + } + unordered_map::hash_type, vector, pair_hash> b_row; + hash_vec hs(max(n, m) + 1); + for (int i = 0; i < n; ++i) { + vector r = b[i]; + sort(r.begin(), r.end()); + hs.clear(); + for (int j = 0; j < m; ++j) { + hs.push_back(r[j]); + } + b_row[hs.hash()].emplace_back(i); + } + vector row_mapping(n); + for (int i = 0; i < n; ++i) { + hs.clear(); + vector r = a[i]; + sort(r.begin(), r.end()); + for (int j = 0; j < m; ++j) { + hs.push_back(r[j]); + } + if (not b_row.count(hs.hash())) { + cout << "NO\n"; + return; + } + row_mapping[i] = b_row[hs.hash()].back(); + b_row[hs.hash()].pop_back(); + if (b_row[hs.hash()].size() == 0) { + b_row.erase(hs.hash()); + } + } + vector> new_a(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + new_a[row_mapping[i]][j] = a[i][j]; + } + } + unordered_map::hash_type, int, pair_hash> b_col; + for (int j = 0; j < m; ++j) { + hs.clear(); + for (int i = 0; i < n; ++i) { + hs.push_back(b[i][j]); + } + b_col[hs.hash()] += 1; + } + for (int j = 0; j < m; ++j) { + hs.clear(); + for (int i = 0; i < n; ++i) { + hs.push_back(new_a[i][j]); + } + if (b_col[hs.hash()] == 0) { + cout << "NO\n"; + return; + } + b_col[hs.hash()] -= 1; + } + cout << "YES\n"; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1980f1.cc b/src/bin/cf-1980f1.cc new file mode 100644 index 0000000..0fea485 --- /dev/null +++ b/src/bin/cf-1980f1.cc @@ -0,0 +1,611 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:49:19 + * Modified: 2024-06-04 20:28:10 + * Elapsed: 1238 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template> struct sparse_table { + _Op op; + vector> st; + template + sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) { + op = __operation; + int n = distance(__first, __last); + st = vector>(n, vector<_Tp>(int(log2(n) + 1))); + int i = n - 1; + for (auto it = __first; it != __last; ++it) { + st[i][0] = *it; + for (int j = 1; i + (1 << j) <= n; ++j) { + st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); + } + i -= 1; + } + } + _Tp query(size_t __start, size_t __end) { + int s = lg2(__end - __start + 1); + return op(st[__start][s], st[__end - (1 << s) + 1][s]); + } +}; + + +void solve() { + read(ll, n, m); + read(int, k); + readvec(pll, a, k); + vector rev(k); + iota(rev.begin(), rev.end(), 0); + sort_by_key(rev.begin(), rev.end(), [&] (int i) -> pll { return {a[i].first, -a[i].second}; }); + sort_by_key(a.begin(), a.end(), [&] (pll x) -> pll { return {x.first, -x.second}; }); + ll res = 0; + vector ss(k + 1, {m + 1, n + 1}); + vector stale(k); + for (int i = 0; i < k - 1; ++i) { + if (a[i + 1].first == a[i].first) { + stale[i] = 1; + } + } + a.emplace_back(n + 1, m + 1); + vector> st; + st.emplace_back(0, 0, -1); + vector> c(k); + vector val(k + 1); + vector fa(k + 1); + ll curr = 0; + vector tag; + for (int i = 0; i < k; ++i) { + tag.emplace_back(a[i].second, i); + } + sparse_table rmq(tag.rbegin(), tag.rend(), functor(min)); + for (int i = 0; i <= k; ++i) { + while (st.size() and get<1>(st.back()) > a[i].second) { + st.pop_back(); + } + int prev = get<2>(st.back()); + curr = (prev == -1 ? 0 : val[prev]) + (a[i].second - 1) * (a[i].first - get<0>(st.back())); + val[i] = curr; + st.emplace_back(a[i].first, a[i].second, i); + fa[i] = prev; + int l = -1, r = prev - 1; + if (l > r) continue; + while (l < r) { + int mid = l + r + 1 >> 1; + if ((mid == -1 ? 0 : rmq.query(mid, prev - 1).first) <= a[i].second) { + l = mid; + } else { + r = mid - 1; + } + } + if ((l == -1 ? 0 : a[l].second) <= a[i].second) { + ll asdf = (l == -1 ? 0 : val[l]) + (a[i].second - 1) * (a[i].first - (l == -1 ? 0 : a[l].first)); + c[prev][i] = asdf - curr; + // debug(make_tuple(l, prev, rev[prev])); + } + } + curr -= m; + cout << curr << '\n'; + vector d(k); + int ptr = k; + while (fa[ptr] != -1) { + d[rev[fa[ptr]]] = !!c[fa[ptr]][ptr]; + ptr = fa[ptr]; + } + putvec(d); +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1980f2.cc b/src/bin/cf-1980f2.cc new file mode 100644 index 0000000..02e9008 --- /dev/null +++ b/src/bin/cf-1980f2.cc @@ -0,0 +1,610 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:49:19 + * Modified: 2024-06-04 20:28:22 + * Elapsed: 1239 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template> struct sparse_table { + _Op op; + vector> st; + template + sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) { + op = __operation; + int n = distance(__first, __last); + st = vector>(n, vector<_Tp>(int(log2(n) + 1))); + int i = n - 1; + for (auto it = __first; it != __last; ++it) { + st[i][0] = *it; + for (int j = 1; i + (1 << j) <= n; ++j) { + st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); + } + i -= 1; + } + } + _Tp query(size_t __start, size_t __end) { + int s = lg2(__end - __start + 1); + return op(st[__start][s], st[__end - (1 << s) + 1][s]); + } +}; + +void solve() { + read(ll, n, m); + read(int, k); + readvec(pll, a, k); + vector rev(k); + iota(rev.begin(), rev.end(), 0); + sort_by_key(rev.begin(), rev.end(), [&] (int i) -> pll { return {a[i].first, -a[i].second}; }); + sort_by_key(a.begin(), a.end(), [&] (pll x) -> pll { return {x.first, -x.second}; }); + ll res = 0; + vector ss(k + 1, {m + 1, n + 1}); + vector stale(k); + for (int i = 0; i < k - 1; ++i) { + if (a[i + 1].first == a[i].first) { + stale[i] = 1; + } + } + a.emplace_back(n + 1, m + 1); + vector> st; + st.emplace_back(0, 0, -1); + vector> c(k); + vector val(k + 1); + vector fa(k + 1); + ll curr = 0; + vector tag; + for (int i = 0; i < k; ++i) { + tag.emplace_back(a[i].second, i); + } + sparse_table rmq(tag.rbegin(), tag.rend(), functor(min)); + for (int i = 0; i <= k; ++i) { + while (st.size() and get<1>(st.back()) > a[i].second) { + st.pop_back(); + } + int prev = get<2>(st.back()); + curr = (prev == -1 ? 0 : val[prev]) + (a[i].second - 1) * (a[i].first - get<0>(st.back())); + val[i] = curr; + st.emplace_back(a[i].first, a[i].second, i); + fa[i] = prev; + int l = -1, r = prev - 1; + if (l > r) continue; + while (l < r) { + int mid = l + r + 1 >> 1; + if ((mid == -1 ? 0 : rmq.query(mid, prev - 1).first) <= a[i].second) { + l = mid; + } else { + r = mid - 1; + } + } + if ((l == -1 ? 0 : a[l].second) <= a[i].second) { + ll asdf = (l == -1 ? 0 : val[l]) + (a[i].second - 1) * (a[i].first - (l == -1 ? 0 : a[l].first)); + c[prev][i] = asdf - curr; + // debug(make_tuple(l, prev, rev[prev])); + } + } + curr -= m; + cout << curr << '\n'; + vector d(k); + int ptr = k; + while (fa[ptr] != -1) { + d[rev[fa[ptr]]] = c[fa[ptr]][ptr]; + ptr = fa[ptr]; + } + putvec(d); +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1980g.cc b/src/bin/cf-1980g.cc new file mode 100644 index 0000000..839a2af --- /dev/null +++ b/src/bin/cf-1980g.cc @@ -0,0 +1,653 @@ +/** + * Author: subcrip + * Created: 2024-06-04 21:12:25 + * Modified: 2024-06-04 23:19:38 + * Elapsed: 127 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template +struct binary_trie { + vector, DataT, array>> tr; + binary_trie() : tr(1) {} + void emplace(ll x, const DataT& data = {}) { + int ptr = 0; + for (int i = N - 1; ~i; --i) { + int bit = x >> i & 1; + if (not std::get<0>(tr[ptr])[bit]) { + std::get<0>(tr[ptr])[bit] = tr.size(); + tr.emplace_back(); + } + std::get<2>(tr[ptr])[bit] += 1; + ptr = std::get<0>(tr[ptr])[bit]; + } + std::get<1>(tr[ptr]) = data; + } + + /// WARN: Don't try to erase a non-existent element! + void erase(ll x) { + int ptr = 0; + vector st; + for (int i = N - 1; ~i; --i) { + int bit = x >> i & 1; + st.emplace_back(ptr, bit); + ptr = std::get<0>(tr[ptr])[bit]; + } + while (st.size() and std::get<2>(tr[st.back().first])[st.back().second] == 1) { + std::get<0>(tr[st.back().first])[st.back().second] = 0; + std::get<2>(tr[st.back().first])[st.back().second] = 0; + st.pop_back(); + } + tr[ptr] = {}; + } + + optional get(ll x) { + int ptr = 0; + for (int i = N - 1; ~i; --i) { + int bit = x >> i & 1; + if (not std::get<0>(tr[ptr])[bit]) return {}; + ptr = std::get<0>(tr[ptr])[bit]; + } + return { std::get<1>(tr[ptr]) }; + } + + int count_prefix(ll x, int bits = N) { + int ptr = 0; + int res = 0; + for (int i = N - 1; i > max(-1, N - 1 - bits); --i) { + int bit = x >> 1 & 1; + if (not std::get<0>(tr[ptr])[bit]) return 0; + ptr = std::get<0>(tr[ptr])[bit]; + res = std::get<2>(tr[ptr])[bit]; + } + return res; + } + + optional> get_max_xor(ll x) { + int ptr = 0; + ll res = 0; + for (int i = N - 1; ~i; --i) { + int bit = x >> i & 1; + if (std::get<0>(tr[ptr])[1 ^ bit]) { + ptr = std::get<0>(tr[ptr])[1 ^ bit]; + res |= (1 ^ bit) << i; + } else if (std::get<0>(tr[ptr])[bit]) { + ptr = std::get<0>(tr[ptr])[bit]; + res |= bit << i; + } else { + return {}; + } + } + return {{ res, std::get<1>(tr[ptr]) }}; + } +}; + +void solve() { + read(int, n, m); + vector> e(n + 1); + for (int i = 0; i < n - 1; ++i) { + read(int, u, v, w); + edgew(e, u, v, w); + } + array, 2> trie; + vector l(n + 1); + vector pre(n + 1); + auto dfs = [&] (auto dfs, int v, int pa, int layer, int pf) -> void { + l[v] = layer; + pre[v] = pf; + if (trie[layer].count_prefix(pf)) { + trie[layer].emplace(pf, trie[layer].get(pf).value() + 1); + } else { + trie[layer].emplace(pf, 1); + } + for (auto&& [u, w] : e[v]) { + if (u == pa) continue; + dfs(dfs, u, v, 1 ^ layer, pf ^ w); + } + }; + dfs(dfs, 1, 0, 0, 0); + int acc = 0; + while (m--) { + read(char, op); + if (op == '^') { + read(int, y); + acc ^= y; + } else { + read(int, v, x); + int prev_val = pre[v]; + int q = trie[l[v]].get(prev_val).value(); + if (q == 1) { + trie[l[v]].erase(prev_val); + } else { + trie[l[v]].emplace(prev_val, q - 1); + } + int v_pf = l[v] == 1 ? pre[v] ^ acc : pre[v]; + ll res = 0; + // process the odd part + auto u_odd_pf = trie[1].get_max_xor(v_pf ^ acc ^ x); + if (u_odd_pf != nullopt) res = max(res, u_odd_pf->first ^ v_pf ^ acc ^ x); + // process the even part + auto u_even_pf = trie[0].get_max_xor(v_pf ^ x); + if (u_even_pf != nullopt) res = max(res, u_even_pf->first ^ v_pf ^ x); + cout << res << ' '; + trie[l[v]].emplace(prev_val, q); + } + } + cout << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/ctext_out.cc b/src/bin/ctext_out.cc index a390bc2..3a1dbf6 100644 --- a/src/bin/ctext_out.cc +++ b/src/bin/ctext_out.cc @@ -1,10 +1,3 @@ -/** - * Author: subcrip - * Created: 2024-06-02 19:04:46 - * Modified: 2024-06-02 19:52:13 - * Elapsed: 47 minutes - */ - #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** @@ -523,7 +516,7 @@ private: else set(m + 1, t, p * 2 + 1, x, c); pull(p); } - + void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) { if (l <= s && t <= r) { d[p].apply(c, t - s + 1); @@ -565,7 +558,7 @@ public: void set(size_type i, const info_type& c) { set({}, _max, 1, i, c); } - + void range_apply(size_type l, size_type r, const tag_type& c) { range_apply({}, _max, 1, l, r, c); } @@ -590,66 +583,82 @@ public: } }; struct Tag { - int val = 0; + ll val = -INFLL; void apply(const Tag& rhs) { - val = rhs.val; + val = max(val, rhs.val); } }; struct Info { - int val = 0; + ll val = -INFLL; void apply(const Tag& rhs, size_t len) { - val += rhs.val * len; + val = max(val, rhs.val); } }; Info operator+(const Info &a, const Info &b) { - return {a.val + b.val}; + return {max(a.val, b.val)}; } void solve() { - read(int, n); - read(string, s, t); - array, 26> bk; - for (int i = n - 1; ~i; --i) { - bk[s[i] - 'a'].emplace_back(i); - } - ll res = INFLL; - ll cnt = 0; - vector mark(n); - segtree tr(n); - auto get = [&] (int i) -> int { - return i + (i + 1 > n - 1 ? 0 : tr.range_query(i + 1, n - 1).val); - }; - int ptr = 0; + read(int, n, m); + vector> row(n); + segtree big(m), small(m); for (int i = 0; i < n; ++i) { - while (mark[ptr]) ++ptr; - assert(ptr < n); - int x = s[ptr] - 'a', y = t[i] - 'a'; - if (x < y) { - res = min(res, cnt); - } - int f = 0; - for (int j = 0; j < 26; ++j) { - while (bk[j].size() and (mark[bk[j].back()] or get(bk[j].back()) < i)) { - bk[j].pop_back(); - } - if (bk[j].size()) { - if (j < y) { - res = min(res, cnt + get(bk[j].back()) - i); - } else if (j == y) { - f = 1; - mark[bk[j].back()] = 1; - tr.set(bk[j].back(), {1}); - cnt += get(bk[j].back()) - i; - } + for (int j = 0; j < m; ++j) { + read(char, c); + if (c == 'B') { + row[i].emplace_back(j); } } - if (f == 0) break; } - if (res == INFLL) { - cout << -1 << '\n'; - } else { - cout << res << '\n'; + vector> res(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (auto&& j : row[i]) { + big.apply(j, {-i+j}); + small.apply(j, {-i-j}); + } + for (int j = 0; j < m; ++j) { + ll big_query = big.range_query(j, m).val; + ll small_query = small.range_query(0, j).val; + if (big_query != -INFLL) { + res[i][j] = max(res[i][j], i - j + int(big_query)); + } + if (small_query != -INFLL) { + res[i][j] = max(res[i][j], i + j + int(small_query)); + } + } } + for (int j = 0; j < m; ++j) { + big.set(j, {}); + small.set(j, {}); + } + for (int i = n - 1; ~i; --i) { + for (auto&& j : row[i]) { + big.apply(j, {i+j}); + small.apply(j, {i-j}); + } + for (int j = 0; j < m; ++j) { + ll big_query = big.range_query(j, m).val; + ll small_query = small.range_query(0, j).val; + if (big_query != -INFLL) { + res[i][j] = max(res[i][j], - i - j + int(big_query)); + } + if (small_query != -INFLL) { + res[i][j] = max(res[i][j], - i + j + int(small_query)); + } + } + } + int ans = INF; + int x = 0, y = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + if (res[i][j] < ans) { + ans = res[i][j]; + x = i + 1; + y = j + 1; + } + } + } + cout << x << ' ' << y << '\n'; } int main() { diff --git a/src/bin/d.cc b/src/bin/d.cc index dd14c1c..160e655 100644 --- a/src/bin/d.cc +++ b/src/bin/d.cc @@ -1,16 +1,15 @@ /** * Author: subcrip - * Created: 2024-05-27 21:39:24 - * Modified: 2024-05-27 22:45:19 - * Elapsed: 65 minutes + * Created: 2024-06-03 23:04:55 + * Modified: 2024-06-03 23:17:23 + * Elapsed: 12 minutes */ #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -181,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -270,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -425,6 +436,9 @@ istream& operator>>(istream& in, MLLd& num) { } // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } @@ -482,123 +496,44 @@ void dump_ignore() {} void prep() { } -static vector> power1; -static vector> power2; -static const ll b = rd(); -template -struct hash_vec { - using hash_type = pll; - MLL hash1; - MLL hash2; - vector<_Tp> seq; - size_t size() { - return seq.size(); - } - void push_back(const _Tp& x) { - hash1 = hash1 * b + x; - hash2 = hash2 * b + x; - seq.push_back(x); - } - void push_front(const _Tp& x) { - size_t length = size(); - hash1 += x * power1[length]; - hash2 += x * power2[length]; - seq.push_front(x); - } - void pop_back() { - _Tp e = seq.back(); seq.pop_back(); - hash1 = (hash1 - e) / b; - hash2 = (hash2 - e) / b; - } - void pop_front() { - _Tp e = seq.front(); seq.pop_front(); - int length = seq.size(); - hash1 -= e * power1[length]; - hash2 -= e * power2[length]; - } - void set(size_t pos, const _Tp& value) { - int length = seq.size(); - int old_value = seq[pos]; - hash1 += (value - old_value) * power1[length - 1 - pos]; - hash2 += (value - old_value) * power2[length - 1 - pos]; - seq[pos] = value; - } - const _Tp& operator[](size_t pos) { - return seq[pos]; - } - hash_type hash() { - return {hash1.val, hash2.val}; - } - void clear() { - hash1 = 0; - hash2 = 0; - seq.clear(); - } - hash_vec(size_t maxn) { - clear(); - MLL c1 = power1.size() ? power1.back() * b : 1; - MLL c2 = power2.size() ? power2.back() * b : 1; - for (int i = power1.size(); i < maxn; ++i) { - power1.push_back(c1); - power2.push_back(c2); - c1 *= b; - c2 *= b; - } - } - hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) { - for (size_t i = 0; i != maxn; ++i) { - push_back(init_value); - } - } -}; - void solve() { - read(int, n, m); - vector> a(n, vector(m)); - for (int i = 0; i < n; ++i) { - for (int j = 0; j < m; ++j) { - read(char, c); - a[i][j] = c == '1'; + read(int, n); + readvec(int, a, n); + auto check = [&] (int idx) -> bool { + int prev_num = idx == 0 ? a[1] : a[0]; + int prev_gcd = -INF; + for (int i = idx == 0 ? 2 : 1; i < n; ++i) { + if (i == idx) continue; + int curr_gcd = gcd(a[i], prev_num); + if (curr_gcd < prev_gcd) { + return false; + } + prev_gcd = curr_gcd; + prev_num = a[i]; } - } - unordered_map>, pair_hash> dp; - for (int j = 0; j < m; ++j) { - hash_vec v(n); - for (int i = 0; i < n; ++i) { - v.push_back(a[i][j]); - } - for (int i =0; i < n; ++i) { - v.set(i, a[i][j] ^ 1); - dp[v.hash()] = {dp[v.hash()].first + 1, {j, i}}; - v.set(i, a[i][j]); + return true; + }; + int prev_gcd = -INF; + for (int i = 1; i < n; ++i) { + int curr_gcd = gcd(a[i], a[i - 1]); + if (curr_gcd < prev_gcd) { + if ((i - 2 >= 0 and check(i - 2)) or check(i - 1) or check(i)) { + cout << "YES\n"; + } else { + cout << "NO\n"; + } + return; } + prev_gcd = curr_gcd; } - int k = 0; - pair v; - for (auto&& [k1, v1] : dp) { - if (v1.first > k) { - k = v1.first; - v = v1.second; - } - } - vector res(n); - auto [q, p] = v; - for (int i = 0; i < n; ++i) { - res[i] = a[i][q]; - } - res[p] = a[p][q] ^ 1; - cout << k << '\n'; - for (int i = 0; i < n; ++i) { - cout << res[i]; - } - cout << '\n';; + cout << "YES\n"; } int main() { -#if __cplusplus < 201703L or defined(_MSC_VER) and not defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); diff --git a/src/bin/e.cc b/src/bin/e.cc index b428862..ac94213 100644 --- a/src/bin/e.cc +++ b/src/bin/e.cc @@ -1,9 +1,15 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:18:29 + * Modified: 2024-06-03 23:35:27 + * Elapsed: 16 minutes + */ + #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -15,7 +21,7 @@ using namespace std; #define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; constexpr void __() {} #define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() -#define __as_typeof(container) decltype(container)::value_type +#define __as_typeof(container) remove_reference::type /* type aliases */ #if LONG_LONG_MAX != INT64_MAX @@ -67,6 +73,8 @@ using tiid = tuple; using tiii = tuple; template using max_heap = priority_queue; template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; /* constants */ constexpr int INF = 0x3f3f3f3f; @@ -172,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -201,10 +210,17 @@ template pair void __read(T& x) { cin >> x; } template void __read(T& x, U&... args) { cin >> x; __read(args...); } #define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) -#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) -#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) #define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) #define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} template ostream& operator<<(ostream& out, const pair& p) { out << "{" << p.first << ", " << p.second << "}"; return out; @@ -254,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -372,77 +399,248 @@ template struct MLL { void operator/=(const MLL& rhs) { val = (*this / rhs).val; } void operator%=(const MLL& rhs) { val = (*this % rhs).val; } }; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; template ostream& operator<<(ostream& out, const MLL& num) { return out << num.val; } +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + template istream& operator>>(istream& in, MLL& num) { return in >> num.val; } +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); } +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} ///////////////////////////////////////////////////////// -#define SINGLE_TEST_CASE +// #define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 void dump() {} void dump_ignore() {} -void prep() {} +void prep() { +} + +static vector> power1; +static vector> power2; +static const ll b = rd(); +template +struct hash_vec { + using hash_type = pll; + MLL hash1; + MLL hash2; + vector<_Tp> seq; + size_t size() { + return seq.size(); + } + void push_back(const _Tp& x) { + hash1 = hash1 * b + x; + hash2 = hash2 * b + x; + seq.push_back(x); + } + void push_front(const _Tp& x) { + size_t length = size(); + hash1 += x * power1[length]; + hash2 += x * power2[length]; + seq.push_front(x); + } + void pop_back() { + _Tp e = seq.back(); seq.pop_back(); + hash1 = (hash1 - e) / b; + hash2 = (hash2 - e) / b; + } + void pop_front() { + _Tp e = seq.front(); seq.pop_front(); + int length = seq.size(); + hash1 -= e * power1[length]; + hash2 -= e * power2[length]; + } + void set(size_t pos, const _Tp& value) { + int length = seq.size(); + int old_value = seq[pos]; + hash1 += (value - old_value) * power1[length - 1 - pos]; + hash2 += (value - old_value) * power2[length - 1 - pos]; + seq[pos] = value; + } + const _Tp& operator[](size_t pos) { + return seq[pos]; + } + hash_type hash() { + return {hash1.val, hash2.val}; + } + void clear() { + hash1 = 0; + hash2 = 0; + seq.clear(); + } + hash_vec(size_t maxn) { + clear(); + MLL c1 = power1.size() ? power1.back() * b : 1; + MLL c2 = power2.size() ? power2.back() * b : 1; + for (int i = power1.size(); i < maxn; ++i) { + power1.push_back(c1); + power2.push_back(c2); + c1 *= b; + c2 *= b; + } + } + hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) { + for (size_t i = 0; i != maxn; ++i) { + push_back(init_value); + } + } +}; void solve() { - read(int, n); - readvec(string, a, n); - vector, int>> trie(1); - auto insert = [&] (const string& s) -> void { - int curr = 0; - vector trace; - for (auto&& x : s) { - if (not trie[curr].first[x - 97]) { - trie[curr].first[x - 97] = trie.size(); - trie.push_back({}); - } - curr = trie[curr].first[x - 97]; - trace.emplace_back(curr); + read(int, n, m); + vector> a(n, vector(m)), b(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> a[i][j]; } - for (auto&& i : trace) { - trie[i].second += 1; - } - }; - auto query = [&] (const string& s) -> ll { - ll res = 0; - int curr = 0; - for (auto&& x : s) { - curr = trie[curr].first[x - 97]; - if (not curr) break; - res += trie[curr].second; - } - return res; - }; - ll res = 0; - for (int i = n - 1; ~i; --i) { - res += query(a[i]); - insert(a[i]); } - cout << res << '\n'; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + cin >> b[i][j]; + } + } + unordered_map::hash_type, vector, pair_hash> b_row; + hash_vec hs(max(n, m) + 1); + for (int i = 0; i < n; ++i) { + vector r = b[i]; + sort(r.begin(), r.end()); + hs.clear(); + for (int j = 0; j < m; ++j) { + hs.push_back(r[j]); + } + b_row[hs.hash()].emplace_back(i); + } + vector row_mapping(n); + for (int i = 0; i < n; ++i) { + hs.clear(); + vector r = a[i]; + sort(r.begin(), r.end()); + for (int j = 0; j < m; ++j) { + hs.push_back(r[j]); + } + if (not b_row.count(hs.hash())) { + cout << "NO\n"; + return; + } + row_mapping[i] = b_row[hs.hash()].back(); + b_row[hs.hash()].pop_back(); + if (b_row[hs.hash()].size() == 0) { + b_row.erase(hs.hash()); + } + } + vector> new_a(n, vector(m)); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + new_a[row_mapping[i]][j] = a[i][j]; + } + } + unordered_map::hash_type, int, pair_hash> b_col; + for (int j = 0; j < m; ++j) { + hs.clear(); + for (int i = 0; i < n; ++i) { + hs.push_back(b[i][j]); + } + b_col[hs.hash()] += 1; + } + for (int j = 0; j < m; ++j) { + hs.clear(); + for (int i = 0; i < n; ++i) { + hs.push_back(new_a[i][j]); + } + if (b_col[hs.hash()] == 0) { + cout << "NO\n"; + return; + } + b_col[hs.hash()] -= 1; + } + cout << "YES\n"; } int main() { -#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); @@ -450,7 +648,7 @@ int main() { read(int, t); for (int i = 0; i < t; ++i) { #ifdef DUMP_TEST_CASE - if (t < (DUMP_TEST_CASE)) { + if (t != (TOT_TEST_CASE)) { solve(); } else if (i + 1 == (DUMP_TEST_CASE)) { dump(); diff --git a/src/bin/f.cc b/src/bin/f.cc index 35f7b1f..780e2f7 100644 --- a/src/bin/f.cc +++ b/src/bin/f.cc @@ -1,9 +1,15 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:49:19 + * Modified: 2024-06-04 01:17:16 + * Elapsed: 87 minutes + */ + #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** - * Useful Macros - * by subcrip - * (requires C++17) + * This code should require C++14. + * However, it's only been tested with C++17. */ #include @@ -15,7 +21,7 @@ using namespace std; #define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; constexpr void __() {} #define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() -#define __as_typeof(container) decltype(container)::value_type +#define __as_typeof(container) remove_reference::type /* type aliases */ #if LONG_LONG_MAX != INT64_MAX @@ -67,6 +73,8 @@ using tiid = tuple; using tiii = tuple; template using max_heap = priority_queue; template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; /* constants */ constexpr int INF = 0x3f3f3f3f; @@ -172,6 +180,7 @@ struct array_hash { }; /* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) #define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) #define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) #define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) @@ -201,10 +210,17 @@ template pair void __read(T& x) { cin >> x; } template void __read(T& x, U&... args) { cin >> x; __read(args...); } #define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) -#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) -#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) #define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) #define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} template ostream& operator<<(ostream& out, const pair& p) { out << "{" << p.first << ", " << p.second << "}"; return out; @@ -254,6 +270,17 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) { #define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) /* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } void __exgcd(ll a, ll b, ll& x, ll& y) { @@ -372,55 +399,196 @@ template struct MLL { void operator/=(const MLL& rhs) { val = (*this / rhs).val; } void operator%=(const MLL& rhs) { val = (*this % rhs).val; } }; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; template ostream& operator<<(ostream& out, const MLL& num) { return out << num.val; } +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + template istream& operator>>(istream& in, MLL& num) { return in >> num.val; } +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + // miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); } template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); } +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} ///////////////////////////////////////////////////////// // #define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 void dump() {} void dump_ignore() {} -void prep() {} - -ll calc(ll r) { - ll res = 0; - for (ll x = -r; x <= r; ++x) { - ll rg = (ll(ceil(sqrt((long double)(r * r) - x * x))) - 1); - if (rg < 0) continue; - else res += 2 * rg + 1; - } - return res; +void prep() { } +template> struct sparse_table { + _Op op; + vector> st; + template + sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) { + op = __operation; + int n = distance(__first, __last); + st = vector>(n, vector<_Tp>(int(log2(n) + 1))); + int i = n - 1; + for (auto it = __first; it != __last; ++it) { + st[i][0] = *it; + for (int j = 1; i + (1 << j) <= n; ++j) { + st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); + } + i -= 1; + } + } + _Tp query(size_t __start, size_t __end) { + int s = lg2(__end - __start + 1); + return op(st[__start][s], st[__end - (1 << s) + 1][s]); + } +}; + + void solve() { - read(ll, r); - cout << calc(r + 1) - calc(r) << '\n'; + read(ll, n, m); + read(int, k); + readvec(pll, a, k); + vector rev(k); + iota(rev.begin(), rev.end(), 0); + sort_by_key(rev.begin(), rev.end(), [&] (int i) -> pll { return {a[i].first, -a[i].second}; }); + sort_by_key(a.begin(), a.end(), [&] (pll x) -> pll { return {x.first, -x.second}; }); + ll res = 0; + vector ss(k + 1, {m + 1, n + 1}); + vector stale(k); + for (int i = 0; i < k - 1; ++i) { + if (a[i + 1].first == a[i].first) { + stale[i] = 1; + } + } + a.emplace_back(n + 1, m + 1); + vector> st; + st.emplace_back(0, 0, -1); + vector> c(k); + vector val(k + 1); + vector fa(k + 1); + ll curr = 0; + vector tag; + for (int i = 0; i < k; ++i) { + tag.emplace_back(a[i].second, i); + } + sparse_table rmq(tag.rbegin(), tag.rend(), functor(min)); + for (int i = 0; i <= k; ++i) { + while (st.size() and get<1>(st.back()) > a[i].second) { + st.pop_back(); + } + int prev = get<2>(st.back()); + curr = (prev == -1 ? 0 : val[prev]) + (a[i].second - 1) * (a[i].first - get<0>(st.back())); + val[i] = curr; + st.emplace_back(a[i].first, a[i].second, i); + fa[i] = prev; + int l = -1, r = prev - 1; + if (l > r) continue; + while (l < r) { + int mid = l + r + 1 >> 1; + if ((mid == -1 ? 0 : rmq.query(mid, prev - 1).first) <= a[i].second) { + l = mid; + } else { + r = mid - 1; + } + } + if ((l == -1 ? 0 : a[l].second) <= a[i].second) { + ll asdf = (l == -1 ? 0 : val[l]) + (a[i].second - 1) * (a[i].first - (l == -1 ? 0 : a[l].first)); + c[prev][i] = asdf - curr; + // debug(make_tuple(l, prev, rev[prev])); + } + } + curr -= m; + cout << curr << '\n'; + vector d(k); + int ptr = k; + while (fa[ptr] != -1) { + d[rev[fa[ptr]]] = c[fa[ptr]][ptr]; + ptr = fa[ptr]; + } + putvec(d); } int main() { -#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) assert(false && "incompatible compiler variant detected."); #endif - untie, cout.tie(NULL); + untie; prep(); #ifdef SINGLE_TEST_CASE solve(); @@ -428,7 +596,7 @@ int main() { read(int, t); for (int i = 0; i < t; ++i) { #ifdef DUMP_TEST_CASE - if (t < (DUMP_TEST_CASE)) { + if (t != (TOT_TEST_CASE)) { solve(); } else if (i + 1 == (DUMP_TEST_CASE)) { dump(); diff --git a/src/bin/f1.cc b/src/bin/f1.cc new file mode 100644 index 0000000..cafa5f4 --- /dev/null +++ b/src/bin/f1.cc @@ -0,0 +1,611 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:49:19 + * Modified: 2024-06-04 01:18:51 + * Elapsed: 89 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template> struct sparse_table { + _Op op; + vector> st; + template + sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) { + op = __operation; + int n = distance(__first, __last); + st = vector>(n, vector<_Tp>(int(log2(n) + 1))); + int i = n - 1; + for (auto it = __first; it != __last; ++it) { + st[i][0] = *it; + for (int j = 1; i + (1 << j) <= n; ++j) { + st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); + } + i -= 1; + } + } + _Tp query(size_t __start, size_t __end) { + int s = lg2(__end - __start + 1); + return op(st[__start][s], st[__end - (1 << s) + 1][s]); + } +}; + + +void solve() { + read(ll, n, m); + read(int, k); + readvec(pll, a, k); + vector rev(k); + iota(rev.begin(), rev.end(), 0); + sort_by_key(rev.begin(), rev.end(), [&] (int i) -> pll { return {a[i].first, -a[i].second}; }); + sort_by_key(a.begin(), a.end(), [&] (pll x) -> pll { return {x.first, -x.second}; }); + ll res = 0; + vector ss(k + 1, {m + 1, n + 1}); + vector stale(k); + for (int i = 0; i < k - 1; ++i) { + if (a[i + 1].first == a[i].first) { + stale[i] = 1; + } + } + a.emplace_back(n + 1, m + 1); + vector> st; + st.emplace_back(0, 0, -1); + vector> c(k); + vector val(k + 1); + vector fa(k + 1); + ll curr = 0; + vector tag; + for (int i = 0; i < k; ++i) { + tag.emplace_back(a[i].second, i); + } + sparse_table rmq(tag.rbegin(), tag.rend(), functor(min)); + for (int i = 0; i <= k; ++i) { + while (st.size() and get<1>(st.back()) > a[i].second) { + st.pop_back(); + } + int prev = get<2>(st.back()); + curr = (prev == -1 ? 0 : val[prev]) + (a[i].second - 1) * (a[i].first - get<0>(st.back())); + val[i] = curr; + st.emplace_back(a[i].first, a[i].second, i); + fa[i] = prev; + int l = -1, r = prev - 1; + if (l > r) continue; + while (l < r) { + int mid = l + r + 1 >> 1; + if ((mid == -1 ? 0 : rmq.query(mid, prev - 1).first) <= a[i].second) { + l = mid; + } else { + r = mid - 1; + } + } + if ((l == -1 ? 0 : a[l].second) <= a[i].second) { + ll asdf = (l == -1 ? 0 : val[l]) + (a[i].second - 1) * (a[i].first - (l == -1 ? 0 : a[l].first)); + c[prev][i] = asdf - curr; + // debug(make_tuple(l, prev, rev[prev])); + } + } + curr -= m; + cout << curr << '\n'; + vector d(k); + int ptr = k; + while (fa[ptr] != -1) { + d[rev[fa[ptr]]] = !!c[fa[ptr]][ptr]; + ptr = fa[ptr]; + } + putvec(d); +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/f2.cc b/src/bin/f2.cc new file mode 100644 index 0000000..b4f3f3e --- /dev/null +++ b/src/bin/f2.cc @@ -0,0 +1,603 @@ +/** + * Author: subcrip + * Created: 2024-06-03 23:49:19 + * Modified: 2024-06-04 08:16:51 + * Elapsed: 507 minutes + */ + +#pragma GCC optimize("Ofast") +///////////////////////////////////////////////////////// +/** + * This code should require C++14. + * However, it's only been tested with C++17. + */ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +using ld = long double; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; +using pid = pair; +using pdi = pair; +using pld = pair; +using pdl = pair; +using pdd = pair; +using tlll = tuple; +using tlld = tuple; +using tlli = tuple; +using tldl = tuple; +using tldd = tuple; +using tldi = tuple; +using tlil = tuple; +using tlid = tuple; +using tlii = tuple; +using tdll = tuple; +using tdld = tuple; +using tdli = tuple; +using tddl = tuple; +using tddd = tuple; +using tddi = tuple; +using tdil = tuple; +using tdid = tuple; +using tdii = tuple; +using till = tuple; +using tild = tuple; +using tili = tuple; +using tidl = tuple; +using tidd = tuple; +using tidi = tuple; +using tiil = tuple; +using tiid = tuple; +using tiii = tuple; +template using max_heap = priority_queue; +template using min_heap = priority_queue, greater<>>; +template using oi = ostream_iterator; +template using ii = istream_iterator; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) +#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template istream& operator>>(istream& in, pair& p) { + return in >> p.first >> p.second; +} +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +template +return_t qpow(ll b, ll p) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + return_t half = qpow(b, p / 2); + if (p % 2 == 1) return half * half * b; + else return half * half; +} + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) + +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + // return (factor, count, factor ** count) + vector> res; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + int cnt = 0; + ll pw = 1; + while (x % i == 0) ++cnt, x /= i, pw *= i; + res.emplace_back(i, cnt, pw); + } + } + if (x != 1) { + res.emplace_back(x, 1, x); + } + return res; +} + +vector decompose_prime(int N) { + // return (factor, count) + vector result; + for (int i = 2; i * i <= N; i++) { + if (N % i == 0) { + int cnt = 0; + while (N % i == 0) N /= i, ++cnt; + result.emplace_back(i, cnt); + } + } + if (N != 1) { + result.emplace_back(N, 1); + } + return result; +} + +/* string algorithms */ +vector calc_next(string t) { // pi function of t + int n = (int)t.length(); + vector pi(n); + for (int i = 1; i < n; i++) { + int j = pi[i - 1]; + while (j > 0 && t[i] != t[j]) j = pi[j - 1]; + if (t[i] == t[j]) j++; + pi[i] = j; + } + return pi; +} +vector calc_z(string t) { // z function of t + int m = t.length(); + vector z; + z.push_back(m); + pair prev = {1, -1}; + for (int i = 1; i < m; ++i) { + if (z[i - prev.first] + i <= prev.second) { + z.push_back(z[i - prev.first]); + } else { + int j = max(i, prev.second + 1); + while (j < m && t[j] == t[j - i]) ++j; + z.push_back(j - i); + prev = {i, j - 1}; + } + } + return z; +} +vector kmp(string s, string t) { // find all t in s + string cur = t + '#' + s; + int sz1 = s.size(), sz2 = t.size(); + vector v; + vector lps = calc_next(cur); + for (int i = sz2 + 1; i <= sz1 + sz2; i++) { + if (lps[i] == sz2) v.push_back(i - 2 * sz2); + } + return v; +} +int period(string s) { // find the length of shortest recurring period + int n = s.length(); + auto z = calc_z(s); + for (int i = 1; i <= n / 2; ++i) { + if (n % i == 0 && z[i] == n - i) { + return i; + } + } + return n; +} + +/* modular arithmetic */ +template struct MLL { + ll val; + MLL(ll v = 0) : val(mod(v, mdl)) {} + MLL(const MLL& other) : val(other.val) {} + friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } + friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } + friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } + friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } + friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } + friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLL& rhs) { val = (*this + rhs).val; } + void operator-=(const MLL& rhs) { val = (*this - rhs).val; } + void operator*=(const MLL& rhs) { val = (*this * rhs).val; } + void operator/=(const MLL& rhs) { val = (*this / rhs).val; } + void operator%=(const MLL& rhs) { val = (*this % rhs).val; } +}; +struct MLLd { + ll val, mdl; + MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} + MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} + friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } + friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } + friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } + friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } + friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } + friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } + friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } + void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } + void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } + void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } + void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } + void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +ostream& operator<<(ostream& out, const MLLd& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +istream& operator>>(istream& in, MLLd& num) { + return in >> num.val; +} + +// miscancellous +#define functor(func) [&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); +} +template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { + std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); +} +template +vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { + vector> res; + auto a_it = a_first; + auto b_it = b_first; + for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { + res.emplace_back(*a_it, *b_it); + } + return res; +} +template +vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { + vector> res; + if (n > 0) { + res.emplace_back(*a_first, *b_first); + for (size_t i = 1; i != n; ++i) { + res.emplace_back(*++a_first, *++b_first); + } + } + return res; +} +template +class ArithmeticIterator : bidirectional_iterator_tag { +public: + using difference_type = ptrdiff_t; + using value_type = T; +private: + value_type value; +public: + ArithmeticIterator(const T& value) : value(value) {} + value_type operator*() const { return value; } + ArithmeticIterator& operator++() { ++value; return *this; } + ArithmeticIterator& operator--() { --value; return *this; } + bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } +}; +template vector> enumerate(const vector& container) { + return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template> struct sparse_table { + _Op op; + vector> st; + template + sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) { + op = __operation; + int n = distance(__first, __last); + st = vector>(n, vector<_Tp>(int(log2(n) + 1))); + int i = n - 1; + for (auto it = __first; it != __last; ++it) { + st[i][0] = *it; + for (int j = 1; i + (1 << j) <= n; ++j) { + st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); + } + i -= 1; + } + } + _Tp query(size_t __start, size_t __end) { + int s = lg2(__end - __start + 1); + return op(st[__start][s], st[__end - (1 << s) + 1][s]); + } +}; + +void solve() { + read(ll, n, m); + read(int, k); + readvec(pll, a, k); + vector rev(k); + iota(rev.begin(), rev.end(), 0); + sort_by_key(rev.begin(), rev.end(), [&] (int i) -> pll { return {a[i].first, -a[i].second}; }); + sort_by_key(a.begin(), a.end(), [&] (pll x) -> pll { return {x.first, -x.second}; }); + ll res = 0; + a.emplace_back(n + 1, m + 1); + vector> st; + st.emplace_back(0, 0, -1); + vector> c(k); + vector val(k + 1); + vector fa(k + 1); + ll curr = 0; + vector tag; + for (int i = 0; i < k; ++i) { + tag.emplace_back(a[i].second, i); + } + sparse_table rmq(tag.rbegin(), tag.rend(), functor(min)); + for (int i = 0; i <= k; ++i) { + while (st.size() and get<1>(st.back()) > a[i].second) { + st.pop_back(); + } + int prev = get<2>(st.back()); + curr = (prev == -1 ? 0 : val[prev]) + (a[i].second - 1) * (a[i].first - get<0>(st.back())); + val[i] = curr; + st.emplace_back(a[i].first, a[i].second, i); + fa[i] = prev; + int l = -1, r = prev - 1; + if (l > r) continue; + while (l < r) { + int mid = l + r + 1 >> 1; + if ((mid == -1 ? 0 : rmq.query(mid, prev - 1).first) <= a[i].second) { + l = mid; + } else { + r = mid - 1; + } + } + if ((l == -1 ? 0 : a[l].second) <= a[i].second) { + ll asdf = (l == -1 ? 0 : val[l]) + (a[i].second - 1) * (a[i].first - (l == -1 ? 0 : a[l].first)); + c[prev][i] = asdf - curr; + // debug(make_tuple(l, prev, rev[prev])); + } + } + curr -= m; + cout << curr << '\n'; + vector d(k); + int ptr = k; + while (fa[ptr] != -1) { + d[rev[fa[ptr]]] = c[fa[ptr]][ptr]; + ptr = fa[ptr]; + } + putvec(d); +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/std.in b/src/bin/std.in index b640086..12ec86f 100644 --- a/src/bin/std.in +++ b/src/bin/std.in @@ -1,13 +1,29 @@ -4 -1 -a -a -3 -rll -rrr -3 -caa -aca 5 -ababa -aabba +3 2 +BW +WW +WB +3 3 +WWB +WBW +BWW +2 3 +BBB +BBB +5 5 +BWBWB +WBWBW +BWBWB +WBWBW +BWBWB +9 9 +WWWWWWWWW +WWWWWWWWW +BWWWWWWWW +WWWWWWWWW +WWWWBWWWW +WWWWWWWWW +WWWWWWWWW +WWWWWWWWW +WWWWWWWWB + diff --git a/src/bin/test.cc b/src/bin/test.cc index de679bc..a3359cf 100644 --- a/src/bin/test.cc +++ b/src/bin/test.cc @@ -1,704 +1,20 @@ /** * Author: subcrip - * Created: 2024-06-01 13:45:49 - * Modified: 2024-06-02 12:33:56 - * Elapsed: 1368 minutes + * Created: 2024-06-03 15:16:33 + * Modified: 2024-06-05 00:29:02 + * Elapsed: 1992 minutes */ -#pragma GCC optimize("Ofast") -///////////////////////////////////////////////////////// -/** - * This code should require C++14. - * However, it's only been tested with C++17. - */ - -#include +#include +#include using namespace std; -/* macro helpers */ -#define __NARGS(...) std::tuple_size::value -#define __DECOMPOSE_S(a, x) auto x = a; -#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; -constexpr void __() {} -#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() -#define __as_typeof(container) remove_reference::type - -/* type aliases */ -#if LONG_LONG_MAX != INT64_MAX -using ll = int64_t; -using ull = uint64_t; -#else -using ll = long long; -using ull = unsigned long long; -using ld = long double; -#endif -using int128 = __int128_t; -using uint128 = __uint128_t; -using ld = long double; -using pii = pair; -using pil = pair; -using pli = pair; -using pll = pair; -using pid = pair; -using pdi = pair; -using pld = pair; -using pdl = pair; -using pdd = pair; -using tlll = tuple; -using tlld = tuple; -using tlli = tuple; -using tldl = tuple; -using tldd = tuple; -using tldi = tuple; -using tlil = tuple; -using tlid = tuple; -using tlii = tuple; -using tdll = tuple; -using tdld = tuple; -using tdli = tuple; -using tddl = tuple; -using tddd = tuple; -using tddi = tuple; -using tdil = tuple; -using tdid = tuple; -using tdii = tuple; -using till = tuple; -using tild = tuple; -using tili = tuple; -using tidl = tuple; -using tidd = tuple; -using tidi = tuple; -using tiil = tuple; -using tiid = tuple; -using tiii = tuple; -template using max_heap = priority_queue; -template using min_heap = priority_queue, greater<>>; -template using oi = ostream_iterator; -template using ii = istream_iterator; - -/* constants */ -constexpr int INF = 0x3f3f3f3f; -constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; -constexpr ll MDL = 1e9 + 7; -constexpr ll PRIME = 998'244'353; -constexpr ll MDL1 = 8784491; -constexpr ll MDL2 = PRIME; -constexpr int128 INT128_MAX = numeric_limits::max(); -constexpr uint128 UINT128_MAX = numeric_limits::max(); -constexpr int128 INT128_MIN = numeric_limits::min(); -constexpr uint128 UINT128_MIN = numeric_limits::min(); - -/* random */ - -mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); - -/* bit-wise operations */ -#define lowbit(x) ((x) & -(x)) -#define popcount(x) (__builtin_popcountll(ll(x))) -#define parity(x) (__builtin_parityll(ll(x))) -#define msp(x) (63LL - __builtin_clzll(ll(x))) -#define lsp(x) (__builtin_ctzll(ll(x))) - -/* arithmetic operations */ -#define mod(x, y) ((((x) % (y)) + (y)) % (y)) - -/* fast pairs */ -#define upair ull -#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) -#define u1(p) ((p) >> 32) -#define u2(p) ((p) & ((1ULL << 32) - 1)) -#define ult std::less -#define ugt std::greater - -#define ipair ull -#define imake(x, y) (umake(x, y)) -#define i1(p) (int(u1(ll(p)))) -#define i2(p) (ll(u2(p) << 32) >> 32) -struct ilt { - bool operator()(const ipair& a, const ipair& b) const { - if (i1(a) == i1(b)) return i2(a) < i2(b); - else return i1(a) < i1(b); - } -}; -struct igt { - bool operator()(const ipair& a, const ipair& b) const { - if (i1(a) == i1(b)) return i2(a) > i2(b); - else return i1(a) > i1(b); - } +struct test { + int val; }; -/* conditions */ -#define loop while (1) -#define if_or(var, val) if (!(var == val)) var = val; else -#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) -#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) - -/* hash */ -struct safe_hash { - // https://codeforces.com/blog/entry/62393 - static uint64_t splitmix64(uint64_t x) { - // http://xorshift.di.unimi.it/splitmix64.c - x += 0x9e3779b97f4a7c15; - x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; - x = (x ^ (x >> 27)) * 0x94d049bb133111eb; - return x ^ (x >> 31); - } - - size_t operator()(uint64_t x) const { - static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); - return splitmix64(x + FIXED_RANDOM); - } -}; - -struct pair_hash { - template - size_t operator()(const pair& a) const { - auto hash1 = safe_hash()(a.first); - auto hash2 = safe_hash()(a.second); - if (hash1 != hash2) { - return hash1 ^ hash2; - } - return hash1; - } -}; - -uniform_int_distribution dist(PRIME); -const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); -struct array_hash { - template - size_t operator()(const Sequence& arr) const { - size_t pw1 = 1, pw2 = 1; - size_t res1 = 0, res2 = 0; - for (auto&& x : arr) { - res1 = (res1 + x * pw1) % __array_hash_mdl1; - res2 = (res2 + x * pw2) % __array_hash_mdl2; - pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; - pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; - } - return res1 + res2; - } -}; - -/* build data structures */ -#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);) -#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) -#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) -#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) -#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) -#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) -#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) -#define edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w), ch[v].emplace_back(u, w);) -#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) -#define Edgew(ch, u, v, w) __AS_PROCEDURE(ch[u].emplace_back(v, w);) -template pair> discretize(Iterator __first, Iterator __last) { - set st(__first, __last); - size_t N = 0; - map mp; - for (auto&& x : st) mp[x] = ++N; - return {N, mp}; -} -template pair> unordered_discretize(Iterator __first, Iterator __last) { - set st(__first, __last); - size_t N = 0; - unordered_map mp; - for (auto&& x : st) mp[x] = ++N; - return {N, mp}; -} - -/* io */ -#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) -template void __read(T& x) { cin >> x; } -template void __read(T& x, U&... args) { cin >> x; __read(args...); } -#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) -#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (auto& x : a) cin >> x;) -#define readvec1(type, a, n) __AS_PROCEDURE(vector a((n) + 1); copy_n(ii(cin), (n), a.begin() + 1);) -#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) -#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) -#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) -#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) -#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) -#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) -template istream& operator>>(istream& in, pair& p) { - return in >> p.first >> p.second; -} -template ostream& operator<<(ostream& out, const pair& p) { - out << "{" << p.first << ", " << p.second << "}"; - return out; -} -template -void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { - using swallow = int[]; // guaranties left to right order - (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; -} -template -decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { - os << "{"; - print_tuple_impl(os, t, std::index_sequence_for{}); - return os << "}"; -} -template ostream& operator<<(ostream& out, const vector& vec) { - for (auto&& i : vec) out << i << ' '; - return out; -} -std::ostream& operator<<(std::ostream& dest, const int128& value) { - // https://stackoverflow.com/a/25115163/23881100 - std::ostream::sentry s( dest ); - if ( s ) { - uint128 tmp = value < 0 ? -value : value; - char buffer[ 128 ]; - char* d = std::end( buffer ); - do { - -- d; - *d = "0123456789"[ tmp % 10 ]; - tmp /= 10; - } while ( tmp != 0 ); - if ( value < 0 ) { - -- d; - *d = '-'; - } - int len = std::end( buffer ) - d; - if ( dest.rdbuf()->sputn( d, len ) != len ) { - dest.setstate( std::ios_base::badbit ); - } - } - return dest; -} - -/* pops */ -#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) -#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) -#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) - -/* math */ -template -return_t qpow(ll b, ll p) { - if (b == 0 and p != 0) return 0; - if (p == 0) return 1; - return_t half = qpow(b, p / 2); - if (p % 2 == 1) return half * half * b; - else return half * half; -} - -#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) - -constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } - -void __exgcd(ll a, ll b, ll& x, ll& y) { - if (b == 0) { - x = 1, y = 0; - return; - } - __exgcd(b, a % b, y, x); - y -= a / b * x; -} - -ll inverse(ll a, ll b) { - ll x, y; - __exgcd(a, b, x, y); - return mod(x, b); -} - -vector> decompose(ll x) { - // return (factor, count, factor ** count) - vector> res; - for (int i = 2; i * i <= x; i++) { - if (x % i == 0) { - int cnt = 0; - ll pw = 1; - while (x % i == 0) ++cnt, x /= i, pw *= i; - res.emplace_back(i, cnt, pw); - } - } - if (x != 1) { - res.emplace_back(x, 1, x); - } - return res; -} - -vector decompose_prime(int N) { - // return (factor, count) - vector result; - for (int i = 2; i * i <= N; i++) { - if (N % i == 0) { - int cnt = 0; - while (N % i == 0) N /= i, ++cnt; - result.emplace_back(i, cnt); - } - } - if (N != 1) { - result.emplace_back(N, 1); - } - return result; -} - -/* string algorithms */ -vector calc_next(string t) { // pi function of t - int n = (int)t.length(); - vector pi(n); - for (int i = 1; i < n; i++) { - int j = pi[i - 1]; - while (j > 0 && t[i] != t[j]) j = pi[j - 1]; - if (t[i] == t[j]) j++; - pi[i] = j; - } - return pi; -} -vector calc_z(string t) { // z function of t - int m = t.length(); - vector z; - z.push_back(m); - pair prev = {1, -1}; - for (int i = 1; i < m; ++i) { - if (z[i - prev.first] + i <= prev.second) { - z.push_back(z[i - prev.first]); - } else { - int j = max(i, prev.second + 1); - while (j < m && t[j] == t[j - i]) ++j; - z.push_back(j - i); - prev = {i, j - 1}; - } - } - return z; -} -vector kmp(string s, string t) { // find all t in s - string cur = t + '#' + s; - int sz1 = s.size(), sz2 = t.size(); - vector v; - vector lps = calc_next(cur); - for (int i = sz2 + 1; i <= sz1 + sz2; i++) { - if (lps[i] == sz2) v.push_back(i - 2 * sz2); - } - return v; -} -int period(string s) { // find the length of shortest recurring period - int n = s.length(); - auto z = calc_z(s); - for (int i = 1; i <= n / 2; ++i) { - if (n % i == 0 && z[i] == n - i) { - return i; - } - } - return n; -} - -/* modular arithmetic */ -template struct MLL { - ll val; - MLL(ll v = 0) : val(mod(v, mdl)) {} - MLL(const MLL& other) : val(other.val) {} - friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); } - friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); } - friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); } - friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); } - friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); } - friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; } - friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; } - void operator+=(const MLL& rhs) { val = (*this + rhs).val; } - void operator-=(const MLL& rhs) { val = (*this - rhs).val; } - void operator*=(const MLL& rhs) { val = (*this * rhs).val; } - void operator/=(const MLL& rhs) { val = (*this / rhs).val; } - void operator%=(const MLL& rhs) { val = (*this % rhs).val; } -}; -struct MLLd { - ll val, mdl; - MLLd(ll mdl, ll v = 0) : mdl(mdl), val(mod(v, mdl)) {} - MLLd(const MLLd& other) : mdl(other.mdl), val(other.val) {} - friend MLLd operator+(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val + rhs.val, lhs.mdl)); } - friend MLLd operator-(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - rhs.val, lhs.mdl)); } - friend MLLd operator*(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * rhs.val, lhs.mdl)); } - friend MLLd operator/(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val * mod(inverse(rhs.val, lhs.mdl), lhs.mdl), lhs.mdl)); } - friend MLLd operator%(const MLLd& lhs, const MLLd& rhs) { return MLLd(lhs.mdl, mod(lhs.val - (lhs / rhs).val, lhs.mdl)); } - friend bool operator==(const MLLd& lhs, const MLLd& rhs) { return lhs.val == rhs.val; } - friend bool operator!=(const MLLd& lhs, const MLLd& rhs) { return lhs.val != rhs.val; } - void operator+=(const MLLd& rhs) { val = (*this + rhs).val; } - void operator-=(const MLLd& rhs) { val = (*this - rhs).val; } - void operator*=(const MLLd& rhs) { val = (*this * rhs).val; } - void operator/=(const MLLd& rhs) { val = (*this / rhs).val; } - void operator%=(const MLLd& rhs) { val = (*this % rhs).val; } -}; - -template -ostream& operator<<(ostream& out, const MLL& num) { - return out << num.val; -} - -ostream& operator<<(ostream& out, const MLLd& num) { - return out << num.val; -} - -template -istream& operator>>(istream& in, MLL& num) { - return in >> num.val; -} - -istream& operator>>(istream& in, MLLd& num) { - return in >> num.val; -} - -// miscancellous -#define functor(func) [&](auto&&... val) \ -noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ -{return func(std::forward(val)...);} -template void sort_by_key(RandomIt first, RandomIt last, Func extractor) { - std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); }); -} -template void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) { - std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); }); -} -template -vector> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) { - vector> res; - auto a_it = a_first; - auto b_it = b_first; - for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) { - res.emplace_back(*a_it, *b_it); - } - return res; -} -template -vector> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) { - vector> res; - if (n > 0) { - res.emplace_back(*a_first, *b_first); - for (size_t i = 1; i != n; ++i) { - res.emplace_back(*++a_first, *++b_first); - } - } - return res; -} -template -class ArithmeticIterator : bidirectional_iterator_tag { -public: - using difference_type = ptrdiff_t; - using value_type = T; -private: - value_type value; -public: - ArithmeticIterator(const T& value) : value(value) {} - value_type operator*() const { return value; } - ArithmeticIterator& operator++() { ++value; return *this; } - ArithmeticIterator& operator--() { --value; return *this; } - bool operator==(const ArithmeticIterator& rhs) const { return value == rhs.value; } -}; -template vector> enumerate(const vector& container) { - return zip(ArithmeticIterator(0), ArithmeticIterator(INT_MAX), container.begin(), container.end()); -} -///////////////////////////////////////////////////////// - -#define SINGLE_TEST_CASE -// #define DUMP_TEST_CASE 7219 -// #define TOT_TEST_CASE 10000 - -void dump() {} - -void dump_ignore() {} - -void prep() { -} - -constexpr int MAXN = 5010; -int low[MAXN], dfn[MAXN], dfs_clock; -bool isbridge[MAXN]; -vector ch[MAXN]; -int cnt_bridge; -int father[MAXN]; - -void tarjan(int u, int fa) { - father[u] = fa; - low[u] = dfn[u] = ++dfs_clock; - for (int i = 0; i < ch[u].size(); i++) { - int v = ch[u][i]; - if (!dfn[v]) { - tarjan(v, u); - low[u] = min(low[u], low[v]); - if (low[v] > dfn[u]) { - isbridge[v] = true; - ++cnt_bridge; - } - } else if (dfn[v] < dfn[u] && v != fa) { - low[u] = min(low[u], dfn[v]); - } - } -} - -struct LCA { - vector depth; - vector> pa; - LCA(const vector>& g, int root = 1) { - int n = g.size() - 1; - int m = 32 - __builtin_clz(n); - depth.resize(n + 1); - pa.resize(n + 1, vector(m, -1)); - function dfs = [&](int x, int fa) { - pa[x][0] = fa; - for (auto&& [y, _, ___] : g[x]) { - if (y != fa) { - depth[y] = depth[x] + 1; - dfs(y, x); - } - } - }; - dfs(root, 0); - - for (int i = 0; i < m - 1; i++) - for (int x = 1; x <= n; x++) - if (int p = pa[x][i]; p != -1) - pa[x][i + 1] = pa[p][i]; - } - - int get_kth_ancestor(int node, int k) { - for (; k; k &= k - 1) - node = pa[node][__builtin_ctz(k)]; - return node; - } - - int query(int x, int y) { - if (depth[x] > depth[y]) - swap(x, y); - y = get_kth_ancestor(y, depth[y] - depth[x]); - if (y == x) - return x; - for (int i = pa[x].size() - 1; i >= 0; i--) { - int px = pa[x][i], py = pa[y][i]; - if (px != py) { - x = px; - y = py; - } - } - return pa[x][0]; - } -}; - - -void solve() { - read(int, n, m); - vector edges; - unordered_set oc; - while (m--){ - read(int, x, y); - if (x == y or oc.count(minmax(x, y))) continue; - oc.insert(minmax(x, y)); - edges.emplace_back(x, y); - edge(ch, x, y); - } - tarjan(1, 0); - // for (int i = 1; i <= n; ++i) { - // debug(isbridge[i]); - // } - adj(sp, n); - for (auto&& [u, v] : edges) { - if (isbridge[u] and minmax(u, v) == minmax(father[u], u)) continue; - if (isbridge[v] and minmax(u, v) == minmax(father[v], v)) continue; - // debug(make_tuple(u, v)); - edge(sp, u, v); - } - // debugvec(sp); - vector vis(n + 1); - int N = 0; - vector col(n + 1); - vector sz(1); - vector no(n + 1); - auto dfs = [&] (auto dfs, int v) -> void { - if (vis[v]) return; - vis[v] = 1; - col[v] = N; - no[v] = sz[N]; - sz[N] += 1; - for (auto&& u : sp[v]) { - if (vis[u]) continue; - dfs(dfs, u); - break; - } - }; - for (int i = 1; i <= n; ++i) { - if (vis[i]) continue; - ++N; - sz.emplace_back(0); - dfs(dfs, i); - } - // debug(col); - vector> nch(N + 1); - for (auto&& [u, v] : edges) { - if (col[u] == col[v]) continue; - nch[col[u]].emplace_back(col[v], u, v); - nch[col[v]].emplace_back(col[u], v, u); - } - vector> branch(N + 1, vector(N + 1)); - vector branch_up(N + 1); - auto dfs2 = [&] (auto dfs2, int v, int pa) -> vector { - vector chs = {v}; - for (auto&& [u, from, to] : nch[v]) { - if (u == pa) continue; - branch_up[u] = to; - // debug(make_tuple(u, to)); - vector curr = dfs2(dfs2, u, v); - chs.insert(chs.end(), curr.begin(), curr.end()); - for (auto&& x : curr) { - branch[v][x] = from; - } - } - return chs; - }; - dfs2(dfs2, 1, 0); - LCA lca(nch); - auto query_dist = [&] (int v, int u) -> int { - // debug(make_tuple(u, v)); - assert(col[v] == col[u]); - if (no[v] > no[u]) swap(u, v); - // debug(min(no[u] - no[v], no[v] - no[u] + sz[col[v]])); - return min(no[u] - no[v], no[v] - no[u] + sz[col[v]]); - }; - auto query = [&] (int v, int u) -> int { - if (col[v] == col[u]) { - return query_dist(u, v); - } - int p = lca.query(col[u], col[v]); - // debug(make_tuple(v, u)); - if (p == col[u]) { - // debug(1); - // return lca.depth[col[v]] - lca.depth[col[u]] + query_dist(u, branch[col[u]][col[v]]) + query_dist(v, branch_up[col[v]]); - return lca.depth[col[v]] - lca.depth[col[u]] + query_dist(v, branch_up[col[v]]); - } else if (p == col[v]) { - // return lca.depth[col[u]] - lca.depth[col[v]] + query_dist(v, branch[col[v]][col[u]]) + query_dist(u, branch_up[col[u]]); - return lca.depth[col[u]] - lca.depth[col[v]] + query_dist(v, branch[col[v]][col[u]]); - }else { - // debug(make_tuple(p, col[v], col[u])); - // debug(lca.depth[col[u]] - lca.depth[p]); - return lca.depth[col[v]] - lca.depth[p] + lca.depth[col[u]] - lca.depth[p] - + query_dist(v, branch_up[col[v]]);// + query_dist(u, branch_up[col[u]]); - } - }; - read(int, t); - int prev = 1; - while (t--) { - read(int, v); - cout << query(prev, v) << " \n"[t == 0]; - prev = v; - } -} +#define empty (test{}) int main() { -#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) - assert(false && "incompatible compiler variant detected."); -#endif - untie, cout.tie(NULL); - prep(); -#ifdef SINGLE_TEST_CASE - solve(); -#else - read(int, t); - for (int i = 0; i < t; ++i) { -#ifdef DUMP_TEST_CASE - if (t != (TOT_TEST_CASE)) { - solve(); - } else if (i + 1 == (DUMP_TEST_CASE)) { - dump(); - } else { - dump_ignore(); - } -#else - solve(); -#endif - } -#endif + empty.val; } diff --git a/src/bin/test.py b/src/bin/test.py index 4fdc6ef..f282f80 100644 --- a/src/bin/test.py +++ b/src/bin/test.py @@ -4,8 +4,8 @@ from os import system import io if __name__ == '__main__': - n = 5000 - m = 10000 - t = 200000 - print(n, m) - for _ in range(m): + n = 100000 + print(2) + print(n) + for _ in range(n): + print(0)