diff --git a/src/bin/cf-1353f.cc b/src/bin/cf-1353f.cc new file mode 100644 index 0000000..9bac74c --- /dev/null +++ b/src/bin/cf-1353f.cc @@ -0,0 +1,537 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wshift-op-parentheses" +#pragma GCC diagnostic ignored "-Wlogical-op-parentheses" +#pragma GCC optimize("Ofast") +/************* This code requires 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; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; using pil = pair; using pid = pair; +using pli = pair; using pll = pair; using pld = pair; +using pdi = pair; using pdl = pair; using pdd = pair; +using tiii = tuple; using tiil = tuple; using tiid = tuple; +using tili = tuple; using till = tuple; using tild = tuple; +using tidi = tuple; using tidl = tuple; using tidd = tuple; +using tlii = tuple; using tlil = tuple; using tlid = tuple; +using tlli = tuple; using tlll = tuple; using tlld = tuple; +using tldi = tuple; using tldl = tuple; using tldd = tuple; +using tdii = tuple; using tdil = tuple; using tdid = tuple; +using tdli = tuple; using tdll = tuple; using tdld = tuple; +using tddi = tuple; using tddl = tuple; using tddd = 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, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +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 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; +} +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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* 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)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(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; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#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 initarray(init, N) (__initarray::type, (N)>(init)) +template +array __initarray(const T& init) { + array res; + for (size_t i = 0; i < N; ++i) { + res[i] = init; + } + return res; +} +/*******************************************************/ + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +constexpr int N = 100; +ll dp[N][N][N], ndp[N][N][N]; + +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) { + cin >> a[i][j]; + } + } + + memset(dp, 0x3f, sizeof(dp)); + for (int i = 0; i < n; ++i) { + memset(ndp, 0x3f, sizeof(ndp)); + for (int j = 0; j < m; ++j) { + for (int k = 0; k < n; ++k) { + for (int l = 0; l < m; ++l) { + // (i, j) as minimum + ll p = a[i][j] - i - j; + ll q = a[k][l] - k - l; + ll prev = i == 0 and j == 0 ? 0 : min(i - 1 >= 0 ? dp[j][k][l] : INFLL, j - 1 >= 0 ? ndp[j - 1][k][l] : INFLL); + if (q > p) { + chmin(ndp[j][i][j], prev + (q - p) * (i + j)); + } else { + chmin(ndp[j][k][l], prev + p - q); + } + } + } + } + swap(dp, ndp); + } + + ll res = INFLL; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + chmin(res, dp[m - 1][i][j]); + } + } + 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-1354e.cc b/src/bin/cf-1354e.cc new file mode 100644 index 0000000..2523ebe --- /dev/null +++ b/src/bin/cf-1354e.cc @@ -0,0 +1,597 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wshift-op-parentheses" +#pragma GCC diagnostic ignored "-Wlogical-op-parentheses" +#pragma GCC optimize("Ofast") +/************* This code requires 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; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; using pil = pair; using pid = pair; +using pli = pair; using pll = pair; using pld = pair; +using pdi = pair; using pdl = pair; using pdd = pair; +using tiii = tuple; using tiil = tuple; using tiid = tuple; +using tili = tuple; using till = tuple; using tild = tuple; +using tidi = tuple; using tidl = tuple; using tidd = tuple; +using tlii = tuple; using tlil = tuple; using tlid = tuple; +using tlli = tuple; using tlll = tuple; using tlld = tuple; +using tldi = tuple; using tldl = tuple; using tldd = tuple; +using tdii = tuple; using tdil = tuple; using tdid = tuple; +using tdli = tuple; using tdll = tuple; using tdld = tuple; +using tddi = tuple; using tddl = tuple; using tddd = 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, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +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 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; +} +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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* 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)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(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; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#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 initarray(init, N) (__initarray::type, (N)>(init)) +template +array __initarray(const T& init) { + array res; + for (size_t i = 0; i < N; ++i) { + res[i] = init; + } + return res; +} +/*******************************************************/ + +#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, m); + read(int, n1, n2, n3); + + adj(ch, n); + while (m--) { + read(int, u, v); + edge(ch, u, v); + } + + vector state(n + 1); + vector vis(n + 1); + vector bag(n + 1); + vector> nums; + int tm = 0; + array nw = {}; + int f = 1; + auto dfs = [&] (auto dfs, int v, int curr) -> void { + bag[v] = tm; + state[v] = curr; + nw[curr] += 1; + vis[v] = 1; + + for (auto&& u : ch[v]) { + if (vis[u]) { + if (state[u] != (1 ^ curr)) { + f = 0; + return; + } + continue; + } + dfs(dfs, u, 1 ^ curr); + } + }; + + int pre_val = 0; + for (int i = 1; i <= n; ++i) { + if (not vis[i]) { + nw.fill(0); + dfs(dfs, i, 0); + nums.emplace_back(nw); + ++tm; + pre_val += nw[0]; + } + } + + if (f == 0) { + cout << "NO\n"; + return; + } + + int k = nums.size(); + vector dp(k + 1, vector(n + 1)); + dp[0][pre_val] = 1; + for (int i = 1; i <= k; ++i) { + dp[i] = dp[i - 1]; + for (int j = 0; j <= n; ++j) { + int idx = j - nums[i - 1][0] + nums[i - 1][1]; + if (idx >= 0 and idx <= n) { + dp[i][idx] |= dp[i - 1][j]; + } + } + // debug(dp[i]); + } + + // debug(bag); + // debug(pre_val); + + if (dp[k][n2] == 0) { + cout << "NO\n"; + } else { + cout << "YES\n"; + vector sol2(k); + int val = n2; + for (int i = k; i > 0; --i) { + if (dp[i - 1][val] == 1) { + // don't need to select this element. + ;; + } else { + sol2[i - 1] = 1; + val -= nums[i - 1][1] - nums[i - 1][0]; + } + } + + for (int i = 1; i <= n; ++i) { + if (state[i] == sol2[bag[i]]) { + cout << 2; + } else { + if (n1 > 0) { + cout << 1; + n1 -= 1; + } else { + cout << 3; + } + } + } + + 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/cf-1373e.cc b/src/bin/cf-1373e.cc new file mode 100644 index 0000000..ac6acfd --- /dev/null +++ b/src/bin/cf-1373e.cc @@ -0,0 +1,566 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wshift-op-parentheses" +#pragma GCC diagnostic ignored "-Wlogical-op-parentheses" +#pragma GCC optimize("Ofast") +/************* This code requires 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; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using ld = long double; +using pii = pair; using pil = pair; using pid = pair; +using pli = pair; using pll = pair; using pld = pair; +using pdi = pair; using pdl = pair; using pdd = pair; +using tiii = tuple; using tiil = tuple; using tiid = tuple; +using tili = tuple; using till = tuple; using tild = tuple; +using tidi = tuple; using tidl = tuple; using tidd = tuple; +using tlii = tuple; using tlil = tuple; using tlid = tuple; +using tlli = tuple; using tlll = tuple; using tlld = tuple; +using tldi = tuple; using tldl = tuple; using tldd = tuple; +using tdii = tuple; using tdil = tuple; using tdid = tuple; +using tdli = tuple; using tdll = tuple; using tdld = tuple; +using tddi = tuple; using tddl = tuple; using tddd = 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, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +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 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; +} +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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* 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)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(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; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#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 initarray(init, N) (__initarray::type, (N)>(init)) +template +array __initarray(const T& init) { + array res; + for (size_t i = 0; i < N; ++i) { + res[i] = init; + } + return res; +} +/*******************************************************/ + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +// custom less function +bool compare(const string& a, const string& b) { + if (a.size() < b.size()) return true; + else if (a.size() > b.size()) return false; + else { + int n = a.size(); + for (int i = 0; i < n; ++i) { + if (a[i] < b[i]) { + return true; + } else if (a[i] > b[i]) { + return false; + } + } + return true; + } +} + +void solve() { + read(int, n, k); + k += 1; + + string res(100, '9'); + for (int i = 0; i <= 10; ++i) { + for (int j = 0; j < 10; ++j) { + if (j + k <= 10) { + int target = n - k * i * 9 - (j + j + k - 1) * k / 2; + if (target < 0 or target % k != 0) { + continue; + } + target /= k; + string s = char(j + '0') + string(i, '9'); + while (target) { + int curr = min(9, target); + s += curr + '0'; + target -= curr; + } + reverse(s.begin(), s.end()); + if (compare(s, res)) { + res = s; + } + } else { + int second = j + k - 10; + int first = k - second; + int target = n - first * i * 9 - (j + j + first - 1) * first / 2 - + (0 + second - 1) * second / 2; + if (target - second < 0 or (target - second) % k != 0) { + continue; + } + target = (target - second) / k; + string s = char(j + '0') + string(i, '9'); + int f = 1; + while (target) { + int curr = min(9 - f, target); + s += curr + '0'; + target -= curr; + f = 0; + } + reverse(s.begin(), s.end()); + if (compare(s, res)) { + res = s; + } + } + } + } + if (res.size() == 100) { + cout << -1 << '\n'; + } else { + 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/ctext_out.cc b/src/bin/ctext_out.cc index 05b0bf9..9bac74c 100644 --- a/src/bin/ctext_out.cc +++ b/src/bin/ctext_out.cc @@ -457,7 +457,7 @@ array __initarray(const T& init) { } /*******************************************************/ -#define SINGLE_TEST_CASE +// #define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 // #define TOT_TEST_CASE 10000 @@ -468,77 +468,45 @@ void dump_ignore() {} void prep() { } +constexpr int N = 100; +ll dp[N][N][N], ndp[N][N][N]; + void solve() { read(int, n, m); - vector a(n); - + vector a(n, vector(m)); for (int i = 0; i < n; ++i) { - cin >> a[i].first; + for (int j = 0; j < m; ++j) { + cin >> a[i][j]; + } } + + memset(dp, 0x3f, sizeof(dp)); for (int i = 0; i < n; ++i) { - cin >> a[i].second; - } - - sort_by_key(a.begin(), a.end(), [] (const pii& p) { return -p.second; }); - - int k = min(n, 15); - vector> info(1 << k); - set tm; - for (int i = 0; i < (1 << k); ++i) { - int t = popcount(i); - - for (int j = 0; j < k; ++j) { - if (i & 1 << j) { - info[i][0] += a[j].first; - info[i][1] += a[j].second * --t; - info[i][2] += a[j].second; + memset(ndp, 0x3f, sizeof(ndp)); + for (int j = 0; j < m; ++j) { + for (int k = 0; k < n; ++k) { + for (int l = 0; l < m; ++l) { + // (i, j) as minimum + ll p = a[i][j] - i - j; + ll q = a[k][l] - k - l; + ll prev = i == 0 and j == 0 ? 0 : min(i - 1 >= 0 ? dp[j][k][l] : INFLL, j - 1 >= 0 ? ndp[j - 1][k][l] : INFLL); + if (q > p) { + chmin(ndp[j][i][j], prev + (q - p) * (i + j)); + } else { + chmin(ndp[j][k][l], prev + p - q); + } + } } } - - if (info[i][0] <= m) { - tm.emplace(info[i][0]); - } + swap(dp, ndp); } - map mp; - int N = 0; - for (auto&& x : tm) mp[x] = ++N; - - vector ps(n - k + 1, vector(N + 1)); - for (int i = 0; i <= n - k; ++i) { - vector bk(N + 1); - for (int j = 0; j < (1 << k); ++j) { - if (info[j][0] <= m) { - chmax(bk[mp[info[j][0]]], info[j][1] + info[j][2] * i); - } - } - - for (int j = 1; j <= N; ++j) { - ps[i][j] = max(ps[i][j - 1], bk[j]); + ll res = INFLL; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + chmin(res, dp[m - 1][i][j]); } } - - ll res = 0; - - for (int i = 0; i < (1 << n - k); ++i) { - int t = popcount(i); - ll tot = 0, sum = 0; - - for (int j = 0; j < n - k; ++j) { - if (i & 1 << j) { - tot += a[k + j].first; - sum += a[k + j].second * --t; - } - } - - if (tot > m) continue; - auto it = mp.upper_bound(m - tot); - if (it == mp.begin()) continue; - --it; - - chmax(res, sum + ps[popcount(i)][it->second]); - } - cout << res << '\n'; } diff --git a/src/bin/std.in b/src/bin/std.in index ad7c4cb..789590b 100644 --- a/src/bin/std.in +++ b/src/bin/std.in @@ -1,9 +1,19 @@ 5 -+3 +1 -+4 *1 -*5 *9 -*2 +6 -+5 +3 -2 -1 1 4 -5 4 5 +3 4 +1 2 3 4 +5 6 7 8 +9 10 11 12 +5 5 +2 5 4 8 3 +9 10 11 5 1 +12 8 4 2 5 +2 2 5 4 1 +6 8 2 4 2 +2 2 +100 10 +10 1 +1 2 +123456789876543 987654321234567 +1 1 +42 +