diff --git a/src/bin/.nvim.lua b/src/bin/.nvim.lua index a297068..222c8e1 100644 --- a/src/bin/.nvim.lua +++ b/src/bin/.nvim.lua @@ -1,7 +1,7 @@ vim.api.nvim_create_autocmd("FileType", { pattern = "cpp", callback = function() - vim.api.nvim_buf_set_keymap(0, 'n', "b", '10spte ctext -i $(gcc -xc++ /dev/null -E -Wp,-v 2>&1 | sed -n "s,^ ,,p" | tr "\\n" ",") < % > ctext_out.cc && clang++ -std=c++17 -DONLINE_JUDGE -Wl,-z,stack-size=268435456 -Wall -Ofast -g -fsanitize=address -fsanitize=undefined ctext_out.cc && ./a.out < std.ini', { + vim.api.nvim_buf_set_keymap(0, 'n', "b", '10spte ctext -i $(gcc -xc++ /dev/null -E -Wp,-v 2>&1 | sed -n "s,^ ,,p" | tr "\\n" ",") < % > ctext_out.cc && clang++ -std=c++17 -DONLINE_JUDGE -Wl,-z,stack-size=268435456 -Wall -Ofast -g -fsanitize=address -fsanitize=undefined ctext_out.cc && time ./a.out < std.ini', { silent = true, noremap = true }) diff --git a/src/bin/a.cc b/src/bin/a.cc index 9b7e3f1..6428345 100644 --- a/src/bin/a.cc +++ b/src/bin/a.cc @@ -23,47 +23,22 @@ 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; +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; @@ -211,6 +186,7 @@ template void __read(T& x, U&... args) { cin >> x; __ #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__)) template istream& operator>>(istream& in, pair& p) { return in >> p.first >> p.second; } @@ -429,6 +405,23 @@ istream& operator>>(istream& in, MLLd& num) { } // 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)...);} @@ -487,7 +480,7 @@ array __initarray(const T& init) { } ///////////////////////////////////////////////////////// -// #define SINGLE_TEST_CASE +#define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 // #define TOT_TEST_CASE 10000 @@ -500,8 +493,21 @@ void prep() { void solve() { read(int, n); - readvec(int, a, n); - cout << a[n - 1] + *max_element(a.begin(), a.begin() + n - 1) << '\n'; + read(string, a); + + using mll = MLL; + mll res = 1; + int cnt = 1; + for (int i = 1; i < n; ++i) { + if (a[i] != a[i - 1]) { + cnt += 1; + } else { + res *= (cnt + 1) / 2; + cnt = 1; + } + } + res *= (cnt + 1) / 2; + cout << res << '\n'; } int main() { diff --git a/src/bin/a.out b/src/bin/a.out index 458b7ad..aecb6c4 100755 Binary files a/src/bin/a.out and b/src/bin/a.out differ diff --git a/src/bin/abc-355f.cc b/src/bin/abc-355f.cc new file mode 100644 index 0000000..16c6976 --- /dev/null +++ b/src/bin/abc-355f.cc @@ -0,0 +1,590 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder-ctor" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +class quick_union { +private: + 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, q); + vector edges; + int base = 0; + for (int i = 0; i < n - 1; ++i) { + read(int, u, v, w); + edges.emplace_back(w, u, v); + base += w; + } + sort(edges.begin(), edges.end()); + + vector qe; + for (int i = 0; i < q; ++i) { + read(int, u, v, w); + qe.emplace_back(w, u, v); + } + + vector res(q, INF); + for (int i = 1; i <= 10; ++i) { + quick_union qu(n + 1); + for (auto&& [w, u, v] : edges) { + if (w > i) break; + qu.merge(u, v); + } + for (int j = 0; j < q; ++j) { + auto&& [w, u, v] = qe[j]; + if (qu.connected(u, v) and res[j] == INF) { + res[j] = min(0, w - i); + } + if (w <= i) { + qu.merge(u, v); + } + } + } + + assert(count(res.begin(), res.end(), INF) == 0); + int curr = base; + for (int i = 0; i < q; ++i) { + cout << (curr += 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/abc-357f.cc b/src/bin/abc-357f.cc new file mode 100644 index 0000000..ffde329 --- /dev/null +++ b/src/bin/abc-357f.cc @@ -0,0 +1,663 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +using mll = MLL; + +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 { + mll a = 0, b = 0; + void apply(const Tag& rhs) { + a += rhs.a; + b += rhs.b; + } +}; +struct Info { + mll a_sum = 0, b_sum = 0, val = 0; + void apply(const Tag& rhs, size_t len) { + val += rhs.b * a_sum; + b_sum += rhs.b * len; + val += rhs.a * b_sum; + a_sum += rhs.a * len; + } +}; +Info operator+(const Info &a, const Info &b) { + return { + .a_sum = a.a_sum + b.a_sum, + .b_sum = a.b_sum + b.b_sum, + .val = a.val + b.val, + }; +} + +void solve() { + read(int, n, q); + readvec(mll, a, n); + readvec(mll, b, n); + + + segtree tr(n); + for (int i = 0; i < n; ++i) { + tr.set(i, { a[i], b[i], a[i] * b[i] }); + } + + while (q--) { + read(int, op, l, r); + --l, --r; + if (op == 1) { + read(int, x); + tr.range_apply(l, r, { x, 0 }); + } else if (op == 2) { + read(int, x); + tr.range_apply(l, r, { 0, x }); + } else { + cout << tr.range_query(l, r).val << '\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/abc-359f.cc b/src/bin/abc-359f.cc new file mode 100644 index 0000000..8cfbdbe --- /dev/null +++ b/src/bin/abc-359f.cc @@ -0,0 +1,525 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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); + readvec(int, a, n); + sort(a.begin(), a.end()); + +} + +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/arc-180a.cc b/src/bin/arc-180a.cc new file mode 100644 index 0000000..6428345 --- /dev/null +++ b/src/bin/arc-180a.cc @@ -0,0 +1,537 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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); + read(string, a); + + using mll = MLL; + mll res = 1; + int cnt = 1; + for (int i = 1; i < n; ++i) { + if (a[i] != a[i - 1]) { + cnt += 1; + } else { + res *= (cnt + 1) / 2; + cnt = 1; + } + } + res *= (cnt + 1) / 2; + 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/arc-180b.cc b/src/bin/arc-180b.cc new file mode 100644 index 0000000..4d9aecb --- /dev/null +++ b/src/bin/arc-180b.cc @@ -0,0 +1,549 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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, k); + readvec(int, a, n); + vector res; + while (1) { + int pos = -1; + vector ss(n + 1, INF); + for (int i = n - 1; ~i; --i) { + ss[i] = min(ss[i + 1], a[i]); + } + for (int i = n - k - 1; i >= 0; --i) { + if (ss[i + k] < a[i] and (pos == -1 or a[i] < a[pos])) { + pos = i; + } + } + if (pos == -1) break; + int j = -1; + for (int i = pos + k; i < n; ++i) { + if (a[i] < a[pos] and (j == -1 or a[i] > a[j])) { + j = i; + } + } + swap(a[pos], a[j]); + res.emplace_back(pos + 1, j + 1); + } + cout << res.size() << '\n'; + for (auto&& [x, y] : res) { + 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/arc-180c.cc b/src/bin/arc-180c.cc new file mode 100644 index 0000000..53aa244 --- /dev/null +++ b/src/bin/arc-180c.cc @@ -0,0 +1,552 @@ +#include +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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); + readvec(int, a, n); + constexpr int Z = 1000; + using mll = MLL; + vector dp(n + 1, array()); + + mll res = 1; + dp[0][Z] = 1; + unordered_set oc; + for (int i = 1; i <= n; ++i) { + for (int j = 0; j <= 2 * Z; ++j) { + if (j - a[i - 1] == Z) { + res -= dp[i - 1][j - a[i - 1]]; + if (oc.count(a[i - 1])) { + ;; + } else { + oc.emplace(a[i - 1]); + dp[i][j] += dp[i - 1][j - a[i - 1]]; + } + } else if (j - a[i - 1] >= 0 and j - a[i - 1] <= 2 * Z) { + dp[i][j] += dp[i - 1][j - a[i - 1]]; + } + dp[i][j] += dp[i - 1][j]; + } + } + + debug(accumulate(dp[n].begin(), dp[n].end(), mll(0))); + res += accumulate(dp[n].begin(), dp[n].end(), mll(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/b.cc b/src/bin/b.cc index c8d3263..4d9aecb 100644 --- a/src/bin/b.cc +++ b/src/bin/b.cc @@ -23,47 +23,22 @@ 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; +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; @@ -211,6 +186,7 @@ template void __read(T& x, U&... args) { cin >> x; __ #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__)) template istream& operator>>(istream& in, pair& p) { return in >> p.first >> p.second; } @@ -429,6 +405,23 @@ istream& operator>>(istream& in, MLLd& num) { } // 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)...);} @@ -487,7 +480,7 @@ array __initarray(const T& init) { } ///////////////////////////////////////////////////////// -// #define SINGLE_TEST_CASE +#define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 // #define TOT_TEST_CASE 10000 @@ -499,12 +492,34 @@ void prep() { } void solve() { - read(ll, n, a, b); - auto calc = [&] (ll k) { - k = max(ll(0), min(k, min(n, b))); - return k * (b + 1) - (k + 1) * k / 2 + a * (n - k); - }; - cout << max(calc(b - a - 1), calc(b - a)) << '\n'; + read(int, n, k); + readvec(int, a, n); + vector res; + while (1) { + int pos = -1; + vector ss(n + 1, INF); + for (int i = n - 1; ~i; --i) { + ss[i] = min(ss[i + 1], a[i]); + } + for (int i = n - k - 1; i >= 0; --i) { + if (ss[i + k] < a[i] and (pos == -1 or a[i] < a[pos])) { + pos = i; + } + } + if (pos == -1) break; + int j = -1; + for (int i = pos + k; i < n; ++i) { + if (a[i] < a[pos] and (j == -1 or a[i] > a[j])) { + j = i; + } + } + swap(a[pos], a[j]); + res.emplace_back(pos + 1, j + 1); + } + cout << res.size() << '\n'; + for (auto&& [x, y] : res) { + cout << x << ' ' << y << '\n'; + } } int main() { diff --git a/src/bin/c.cc b/src/bin/c.cc index 68356b3..53aa244 100644 --- a/src/bin/c.cc +++ b/src/bin/c.cc @@ -1,3 +1,4 @@ +#include #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** @@ -23,47 +24,22 @@ 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; +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; @@ -211,6 +187,7 @@ template void __read(T& x, U&... args) { cin >> x; __ #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__)) template istream& operator>>(istream& in, pair& p) { return in >> p.first >> p.second; } @@ -429,6 +406,23 @@ istream& operator>>(istream& in, MLLd& num) { } // 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)...);} @@ -487,7 +481,7 @@ array __initarray(const T& init) { } ///////////////////////////////////////////////////////// -// #define SINGLE_TEST_CASE +#define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 // #define TOT_TEST_CASE 10000 @@ -499,33 +493,36 @@ void prep() { } void solve() { - read(ll, n, k); - if (k & 1) { - cout << "No\n"; - return; - } - vector res(n + 1); - k /= 2; - iota(res.begin(), res.end(), 0); - int mx = n - 1; - int l = 1, r = n; - while (k) { - while (mx > k) { - l += 1; - mx -= 1; + read(int, n); + readvec(int, a, n); + constexpr int Z = 1000; + using mll = MLL; + vector dp(n + 1, array()); + + mll res = 1; + dp[0][Z] = 1; + unordered_set oc; + for (int i = 1; i <= n; ++i) { + for (int j = 0; j <= 2 * Z; ++j) { + if (j - a[i - 1] == Z) { + res -= dp[i - 1][j - a[i - 1]]; + if (oc.count(a[i - 1])) { + ;; + } else { + oc.emplace(a[i - 1]); + dp[i][j] += dp[i - 1][j - a[i - 1]]; + } + } else if (j - a[i - 1] >= 0 and j - a[i - 1] <= 2 * Z) { + dp[i][j] += dp[i - 1][j - a[i - 1]]; + } + dp[i][j] += dp[i - 1][j]; } - if (l >= r) { - cout << "No\n"; - return; - } - k -= mx; - res[l] = r, res[r] = l; - l += 1; - r -= 1; - mx -= 2; } - cout << "Yes\n"; - putvec1(res); + + debug(accumulate(dp[n].begin(), dp[n].end(), mll(0))); + res += accumulate(dp[n].begin(), dp[n].end(), mll(0)); + + cout << res << '\n'; } int main() { diff --git a/src/bin/cf-1534e.cc b/src/bin/cf-1534e.cc new file mode 100644 index 0000000..6812283 --- /dev/null +++ b/src/bin/cf-1534e.cc @@ -0,0 +1,566 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +int query(const vector& a) { + if (a.empty()) return 0; + cout << "?"; + for (auto&& x : a) { + cout << ' ' << x; + } + cout << endl; + read(int, x); + return x; +} + +void solve() { + read(int, n, k); + if ((n % k) & 1) { + cout << -1 << endl; + return; + } + + int ptr = 0; + int res = 0; + for (int i = 0; i < n / k; ++i) { + vector curr; + for (int j = ptr; j < ptr + k; ++j) { + curr.emplace_back(j + 1); + } + ptr += k; + res ^= query(curr); + } + + if (n % k) { + int x = (n % k) / 2; + vector curr; + for (int j = n - x; j > n - x - k; --j) { + curr.emplace_back(j); + } + res ^= query(curr); + curr.clear(); + for (int j = n; j > n - x; --j) { + curr.emplace_back(j); + } + for (int j = n / k * k; j > n - x - k; --j) { + curr.emplace_back(j); + } + res ^= query(curr); + } + cout << "! " << res << endl; +} + +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-1536e.cc b/src/bin/cf-1536e.cc new file mode 100644 index 0000000..7bd22eb --- /dev/null +++ b/src/bin/cf-1536e.cc @@ -0,0 +1,536 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() {} + +constexpr int N = 4000010; +using mll = MLL; +mll pw[N]; +void prep() { + pw[0] = 1; + for (int i = 1; i < N; ++i) { + pw[i] = pw[i - 1] * 2; + } +} + +void solve() { + read(int, n, m); + readvec(char, a, n * m); + int cnt = count(a.begin(), a.end(), '0'); + if (cnt == 0) { + cout << pw[n * m] - 1 << '\n'; + } else { + cout << pw[n * m - cnt] << '\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-1537e1.cc b/src/bin/cf-1537e1.cc new file mode 100644 index 0000000..c0fa16d --- /dev/null +++ b/src/bin/cf-1537e1.cc @@ -0,0 +1,535 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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, k); + read(string, s); + string res(k, 'z'); + for (int i = 1; i <= n; ++i) { + string curr; + int ptr = 0; + for (int j = 0; j < k; ++j) { + curr += s[ptr]; + ptr = (ptr + 1) % i; + } + if (curr < res) res = curr; + } + + 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-1537e2.cc b/src/bin/cf-1537e2.cc new file mode 100644 index 0000000..0a69f64 --- /dev/null +++ b/src/bin/cf-1537e2.cc @@ -0,0 +1,555 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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, k); + read(string, s); + auto z = calc_z(s); + int p = n; + int pos = INF; + char c = 0; + for (int i = 1; i <= n; ++i) { + int curr = i; + if (z[i % n] == n - i) { + curr += n - i; + if (z[n - i] != i) { + curr += z[n - i]; + if (s[curr % i] < s[curr % n] and (curr < pos or curr == pos and s[pos % i] < c)) { + pos = curr; + c = s[pos % i]; + p = i; + } + } + } else { + curr += z[i % n]; + if (s[curr % i] < s[curr % n] and (curr < pos or curr == pos and s[pos % i] < c)) { + pos = curr; + c = s[pos % i]; + p = i; + } + } + } + + int ptr = 0; + for (int i = 0; i < k; ++i) { + cout << s[ptr]; + ptr = (ptr + 1) % p; + } + 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-1538e.cc b/src/bin/cf-1538e.cc new file mode 100644 index 0000000..c1f41cf --- /dev/null +++ b/src/bin/cf-1538e.cc @@ -0,0 +1,635 @@ +#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; +#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 = hash()(a.first); + auto hash2 = 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +struct return_t { + ll length = 0; + string raw = ""; + ll cnt_haha = 0; + int right_h = 0; + int right_ha = 0; + int right_hah = 0; + int left_a = 0; + int left_ha = 0; + int left_aha = 0; +}; + +void solve() { + read(int, n); + unordered_map cnt; + unordered_map, pair, pair>, pair_hash> var; + pair last; + for (int i = 0; i < n; ++i) { + read(string, s, op); + if (op == ":=") { + read(string, v); + var[{cnt[s]++, s}] = { {-1, ""}, {-1, v} }; + } else { + read(string, v1, plus, v2); + var[{cnt[s]++, s}] = { {cnt[v1] - 1, v1}, {cnt[v2] - 1, v2} }; + } + if (i + 1 == n) { + last = { cnt[s] - 1, s }; + } + } + + auto make_raw = [] (const string& v) { + return_t res; + res.length = v.size(); + if (v.size() < 3) { + res.raw = v; + } + for (int i = 0; i + 3 < res.length; ++i) { + if (v.substr(i, 4) == "haha") { + res.cnt_haha = 1; + } + } + if (v.size() >= 3 and v.substr(v.size() - 3, 3) == "hah") { + res.right_hah = 1; + } + if (v.size() >= 2 and v.substr(v.size() - 2, 2) == "ha") { + res.right_ha = 1; + } + if (v[v.size() - 1] == 'h') { + res.right_h = 1; + } + if (v.size() >= 3 and v.substr(0, 3) == "aha") { + res.left_aha = 1; + } + if (v.size() >= 2 and v.substr(0, 2) == "ha") { + res.left_ha = 1; + } + if (v[0] == 'a') { + res.left_a = 1; + } + return res; + }; + + unordered_map, return_t, pair_hash> cache; + auto dfs = [&] (auto dfs, const pair& key) -> return_t { + return_t res; + if (cache.count(key)) { + res = cache[key]; + } else { + if (var[key].first.first == -1) { + res = make_raw(var[key].second.second); + } else { + auto&& [l, r] = var[key]; + return_t left_res = dfs(dfs, l), right_res = dfs(dfs, r); + if (left_res.length + right_res.length < 3) { + res = make_raw(left_res.raw + right_res.raw); + } else { + res.length = left_res.length + right_res.length; + res.cnt_haha = left_res.cnt_haha + right_res.cnt_haha; + if (left_res.right_hah and right_res.left_a) { + res.cnt_haha += 1; + } + if (left_res.right_ha and right_res.left_ha) { + res.cnt_haha += 1; + } + if (left_res.right_h and right_res.left_aha) { + res.cnt_haha += 1; + } + res.right_hah = right_res.right_hah; + res.right_ha = right_res.right_ha; + res.right_h = right_res.right_h; + res.left_aha = left_res.left_aha; + res.left_ha = left_res.left_ha; + res.left_a = left_res.left_a; + if (right_res.raw == "ah" and left_res.right_h or right_res.raw == "h" and left_res.right_ha) { + res.right_hah = 1; + } + if (right_res.raw == "a" and left_res.right_h) { + res.right_ha = 1; + } + if (left_res.raw == "h" and right_res.left_a) { + res.left_ha = 1; + } + if (left_res.raw == "a" and right_res.left_ha or left_res.raw == "ah" and right_res.left_a) { + res.left_aha = 1; + } + } + } + cache[key] = res; + // deb(key, cache[key].cnt_haha, cache[key].right_h, cache[key].left_aha, cache[key].length); + } + return cache[key]; + }; + + cout << dfs(dfs, last).cnt_haha << '\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-1547g.cc b/src/bin/cf-1547g.cc new file mode 100644 index 0000000..7b3f236 --- /dev/null +++ b/src/bin/cf-1547g.cc @@ -0,0 +1,738 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +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); + adj(ch, n); + vector edges; + vector self_loop(n + 1); + for (int i = 0; i < m; ++i) { + read(int, u, v); + if (u != v) { + Edge(ch, u, v); + edges.emplace_back(u, v); + } else { + self_loop[u] = 1; + } + } + auto scc = tarjan::scc(ch); + int N = *max_element(scc.begin(), scc.end()); + + vector rev(N + 1); + for (int i = 1; i <= n; ++i) { + rev[scc[i]] = i; + } + vector cnt(N + 1); + for (int i = 1; i <= n; ++i) { + cnt[scc[i]] += 1; + } + + vector> nch(N + 1); + vector ind(N + 1); + for (auto&& [u, v] : edges) { + if (scc[u] != scc[v] and not nch[scc[u]].count(scc[v])) { + nch[scc[u]].emplace(scc[v]); + ++ind[scc[v]]; + } + } + + deque q; + vector res(N + 1); + for (int i = 1; i <= N; ++i) { + if (not ind[i]) { + q.emplace_back(i); + } + } + + while (q.size()) { + int v = q.front(); q.pop_front(); + if (v == scc[1]) { + res[v] = cnt[v] > 1 or self_loop[rev[v]] ? -1 : 1; + } else if (res[v] and (cnt[v] > 1 or self_loop[rev[v]])) { + res[v] = -1; + } + for (auto&& u : nch[v]) { + if (res[u] == 0) { + if (res[v] != 0) { + res[u] = res[v]; + } + } else if (res[u] == 1) { + if (res[v] == 1 or res[v] == 2) { + res[u] = 2; + } else if (res[v] == -1) { + res[u] = -1; + } + } else if (res[u] == 2) { + if (res[v] == -1) { + res[u] = -1; + } + } + if (--ind[u] == 0) { + q.emplace_back(u); + } + } + } + + for (int i = 1; i <= n; ++i) { + cout << res[scc[i]] << " \n"[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-1550d.cc b/src/bin/cf-1550d.cc new file mode 100644 index 0000000..f302d65 --- /dev/null +++ b/src/bin/cf-1550d.cc @@ -0,0 +1,544 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() {} + +constexpr int N = 2e5 + 10; +using mll = MLL; +mll fact[N]; +void prep() { + fact[0] = 1; + for (int i = 1; i < N; ++i) { + fact[i] = fact[i - 1] * i; + } +} + +void solve() { + read(int, n, l, r); + + mll res = 0; + for (int x = max(1, r - n); x <= min(r - (n + 1) / 2, min(n - l, (r - n - l + 1) / 2)); ++x) { + res += comb(r - x, (n + 1) / 2); + } + res += min(max(0, r - n - 1), n - l) * comb(n, (n + 1) / 2); + + if (n & 1) { + for (int x = max(1, r - n); x <= min(r - n / 2, min(n - l, (r - n - l + 1) / 2)); ++x) { + res += comb(r - x, n / 2); + } + res += min(max(0, r - n - 1), n - l) * comb(n, n / 2); + } + + 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-1553f.cc b/src/bin/cf-1553f.cc new file mode 100644 index 0000000..29c9a4a --- /dev/null +++ b/src/bin/cf-1553f.cc @@ -0,0 +1,661 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { +} + +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 = 0; + void apply(const Tag& rhs) { + val += rhs.val; + } +}; +struct Info { + ll val = 0; + void apply(const Tag& rhs, size_t len) { + val += rhs.val * len; + } +}; +struct WInfo { + ll val = 0, cnt = 0, w = 0; + void apply(const Tag& rhs, size_t len) { + cnt += rhs.val; + val += w * rhs.val; + } +}; +Info operator+(const Info &a, const Info &b) { + return {a.val + b.val}; +} +WInfo operator+(const WInfo &a, const WInfo &b) { + return {a.val + b.val, a.cnt + b.cnt, 0}; +} + +void solve() { + read(int, n); + readvec(ll, a, n); + + constexpr ll N = 3e5 + 10; + segtree tr(N); + segtree tr2(N); + for (int i = 0; i < N; ++i) { + tr2.set(i, { 0, 0, i }); + } + + ll res = 0; + for (int i = 0; i < n; ++i) { + res += a[i] * i - tr.query(a[i]).val; + for (ll j = 0; j < N; j += a[i]) { + tr.range_apply(j, min(N - 1, j + a[i] - 1), { j }); + auto [sum, cnt, _] = tr2.range_query(j, min(N - 1, j + a[i] - 1)); + res += sum - cnt * j; + } + tr2.apply(a[i], { 1 }); + cout << res << " \n"[i + 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-1989c.cc b/src/bin/cf-1989c.cc new file mode 100644 index 0000000..1cc488c --- /dev/null +++ b/src/bin/cf-1989c.cc @@ -0,0 +1,552 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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); + readvec(int, b, n); + readvec(int, c, n); + vector a; + for (int i = 0; i < n; ++i) { + a.emplace_back(b[i], c[i]); + } + int s1 = 0, s2 = 0, cand = 0; + for (int i = 0; i < n; ++i) { + if (a[i].first == 1 and a[i].second == 1) { + s1 += 1, s2 += 1, cand += 1; + } else if (a[i].first == 1 and a[i].second == 0) { + s1 += 1; + } else if (a[i].first == 1 and a[i].second == -1) { + s1 += 1; + } else if (a[i].first == 0 and a[i].second == 1) { + s2 += 1; + } else if (a[i].first == 0 and a[i].second == -1) { + } else if (a[i].first == -1 and a[i].second == 1) { + s2 += 1; + } else if (a[i].first == -1 and a[i].second == 0) { + } else if (a[i].first == -1 and a[i].second == -1) { + cand += 1; + } + } + int res = -INF; + for (int x = 0; x <= cand; ++x) { + int y = cand - x; + chmax(res, min(s1 - x, s2 - y)); + } + 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-1989d.cc b/src/bin/cf-1989d.cc new file mode 100644 index 0000000..533799d --- /dev/null +++ b/src/bin/cf-1989d.cc @@ -0,0 +1,558 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { + constexpr ll N = 1e6 + 10; + read(int, n, m); + readvec(int, b, n); + vector a(N, INF); + for (int i = 0; i < n; ++i) { + read(int, x); + chmin(a[b[i]], b[i] - x); + } + vector ps(N, 0); + for (int i = 1; i < N; ++i) { + if (a[i] < a[ps[i - 1]]) { + ps[i] = i; + } else { + ps[i] = ps[i - 1]; + } + } + vector dp(N); + for (int i = 1; i < N; ++i) { + if (a[ps[i]] == INF) { + dp[i] = 0; + } else { + dp[i] = dp[i - a[ps[i]]] + 1; + } + } + + ll res = 0; + while (m--) { + read(int, x); + ll curr = 0; + if (x >= N) { + curr += (x - N + 1) / a[ps[N - 1]] + 1; + x -= curr * a[ps[N - 1]]; + } + curr += dp[x]; + res += curr; + } + cout << res * 2 << '\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-1989e.cc b/src/bin/cf-1989e.cc new file mode 100644 index 0000000..ae20fed --- /dev/null +++ b/src/bin/cf-1989e.cc @@ -0,0 +1,551 @@ +#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; +#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, 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;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) +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 +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() { + using mll = MLL; + read(int, n, k); + vector last(k + 1); + vector tot(n + 1, vector(k + 1)); + + tot[0][0] = 1; + last[0] = 1; + + for (int i = 1; i <= n; ++i) { + vector curr(k + 1); + if (i - 2 == 0 or i == n) { + for (int j = 0; j <= k; ++j) { + curr[min(k, j + 1)] += tot[i - 2][j]; + } + } else if (i - 3 >= 0) { + for (int j = 0; j <= k; ++j) { + curr[min(k, j + 1)] += tot[i - 3][j]; + } + } + for (int j = 0; j <= k; ++j) { + curr[min(k, j + 1)] += last[j]; + } + + for (int j = 0; j <= k; ++j) { + tot[i][j] = tot[i - 1][j] + curr[j]; + } + last = curr; + } + + cout << last[k] << '\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 30d0d38..4082475 100644 --- a/src/bin/ctext_out.cc +++ b/src/bin/ctext_out.cc @@ -1,3 +1,7 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder" +// #pragma GCC diagnostic ignored "-Wreorder-ctor" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** @@ -492,37 +496,6 @@ void prep() { } void solve() { - read(int, n, k); - vector a; - for (int i = 0; i < n; ++i) { - read(int, x); - --x; - a.emplace_back(x); - } - - vector dp(n + 1, vector(n + 1)); - for (int i = 1; i <= n; ++i) { - // don't remove the current element - for (int j = 0; j <= n; ++j) { - dp[i][j] = dp[i - 1][j] + ((i - 1) - a[i - 1] == j); - } - - // remove the current element - for (int j = 0; j < n; ++j) { - chmax(dp[i][j + 1], dp[i - 1][j]); - } - } - - // debug(dp); - - for (int i = 0; i <= n; ++i) { - if (dp[n][i] >= k) { - cout << i << '\n'; - return; - } - } - - cout << -1 << '\n'; } int main() { diff --git a/src/bin/d.cc b/src/bin/d.cc index 06952d7..533799d 100644 --- a/src/bin/d.cc +++ b/src/bin/d.cc @@ -23,47 +23,22 @@ 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; +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; @@ -211,6 +186,7 @@ template void __read(T& x, U&... args) { cin >> x; __ #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__)) template istream& operator>>(istream& in, pair& p) { return in >> p.first >> p.second; } @@ -429,6 +405,23 @@ istream& operator>>(istream& in, MLLd& num) { } // 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)...);} @@ -487,7 +480,7 @@ array __initarray(const T& init) { } ///////////////////////////////////////////////////////// -// #define SINGLE_TEST_CASE +#define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 // #define TOT_TEST_CASE 10000 @@ -499,30 +492,43 @@ void prep() { } void solve() { - read(int, n, c); - readvec(ll, a, n); - a[0] += c; - vector ps(n + 1), ss(n + 1); - for (int i = 1; i <= n; ++i) { - ps[i] = max(ps[i - 1], a[i - 1]); - } - for (int i = n - 1; ~i; --i) { - ss[i] = max(ss[i + 1], a[i]); - } - ll left = 0; + constexpr ll N = 1e6 + 10; + read(int, n, m); + readvec(int, b, n); + vector a(N, INF); for (int i = 0; i < n; ++i) { - if (ps[i] < a[i] and ss[i + 1] <= a[i]) { - cout << 0; - } else { - int res = i; - if (ss[i + 1] > a[i] + left) { - res += 1; - } - cout << res; - } - cout << " \n"[i + 1 == n]; - left += a[i]; + read(int, x); + chmin(a[b[i]], b[i] - x); } + vector ps(N, 0); + for (int i = 1; i < N; ++i) { + if (a[i] < a[ps[i - 1]]) { + ps[i] = i; + } else { + ps[i] = ps[i - 1]; + } + } + vector dp(N); + for (int i = 1; i < N; ++i) { + if (a[ps[i]] == INF) { + dp[i] = 0; + } else { + dp[i] = dp[i - a[ps[i]]] + 1; + } + } + + ll res = 0; + while (m--) { + read(int, x); + ll curr = 0; + if (x >= N) { + curr += (x - N + 1) / a[ps[N - 1]] + 1; + x -= curr * a[ps[N - 1]]; + } + curr += dp[x]; + res += curr; + } + cout << res * 2 << '\n'; } int main() { diff --git a/src/bin/std.in b/src/bin/std.in index 393f0dd..e437e17 100644 --- a/src/bin/std.in +++ b/src/bin/std.in @@ -1,10 +1,8 @@ -4 -7 6 -1 1 2 3 4 5 6 -5 2 -5 1 3 2 3 -5 2 -5 5 5 5 4 -8 4 -1 2 3 3 2 2 5 5 - +4 4 +1 2 6 +2 3 5 +2 4 4 +1 3 3 +1 2 3 +1 4 10 +3 4 1 diff --git a/src/bin/template.cc b/src/bin/template.cc index 5621bb4..f316c78 100644 --- a/src/bin/template.cc +++ b/src/bin/template.cc @@ -1,3 +1,6 @@ +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#pragma GCC diagnostic ignored "-Wreorder" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC optimize("Ofast") ///////////////////////////////////////////////////////// /** diff --git a/src/bin/test.cc b/src/bin/test.cc index edb3a52..4469875 100644 --- a/src/bin/test.cc +++ b/src/bin/test.cc @@ -1,36 +1,5 @@ #include using namespace std; -class Student_Info { -friend bool compare(Student_Info, Student_Info); -private: - string name; - double grade; - -public: - Student_Info(string name, double grade) { - this->name = name; - this->grade = grade; - } - - string get_name() { - return this->name; - } - -}; - -bool compare(Student_Info a, Student_Info b) { - return a.grade < b.grade; -} - int main() { - vector students = { - Student_Info("John", 8.5), - Student_Info("Bob", 7.5), - Student_Info("Jane", 9.5), - }; - sort(students.begin(), students.end(), compare); - for (auto&& student : students) { - cout << student.get_name() << endl; - } } diff --git a/src/bin/test.py b/src/bin/test.py index 1a394ae..c11d4f6 100644 --- a/src/bin/test.py +++ b/src/bin/test.py @@ -7,16 +7,32 @@ import io PRIME = 998_244_353 if __name__ == '__main__': - a = [(0, 0), (2, 16), (30, 14), (4, 6), (2, 10)] - a.sort(key=lambda t: t[1]) - n = len(a) - res = [] - for i in range(n): - for j in range(i + 1, n): - for k in range(i + 1, j): - # if (a[j][0] - a[i][0]) * (a[k][1] - a[i][1]) % (a[j][1] - a[i][1]): - # continue - x, y = a[i][0] // 2 + (a[j][0] // 2 - a[i][0] // 2) * (a[k][1] // 2 - a[i][1] // 2 + a[j][1] // 2 - a[i][1] // 2 - 1) // (a[j][1] // 2 - a[i][1] // 2) - a[k][0] // 2, a[i][1] // 2 - a[j][1] // 2 - if (x + y) & 1: - res.append((a[i], a[j], a[k], x, y)) - print(res) + n = 4 + k = 5 + for i in range(1 << n * k): + j = i + cnt = (j & ((1 << n) - 1)).bit_count() + f = 1 + for _ in range(k): + if (j & ((1 << n) - 1)).bit_count() != cnt: + f = 0 + break + j >>= n + for j in range(n): + l = i >> j + c = 0 + while l: + c += l & 1 + l >>= n + if (c & 1) == 0: + f = 0 + break + if f: + m = i + for j in range(k): + for l in range(n): + print(m & 1, end='') + m >>= 1 + print() + print() +