diff --git a/src/bin/cf-886e.cc b/src/bin/cf-886e.cc new file mode 100644 index 0000000..632f5fc --- /dev/null +++ b/src/bin/cf-886e.cc @@ -0,0 +1,593 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +using mll = MLL; +constexpr int N = 1e6 + 10; +mll fact[N]; + +void prep() { + fact[0] = 1; + for (int i = 1; i < N; ++i) { + fact[i] = fact[i - 1] * i; + } +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, k); + vector dp(n + 1); + dp[1] = 1; + deque q = { 1 }; + mll sum = 1; + for (int i = 2; i <= n; ++i) { + if (q.size() > k) { + sum -= popfront(q); + } + dp[i] = fact[i - 2] * sum; + mll curr = dp[i] / fact[i - 1]; + q.emplace_back(curr); + sum += curr; + } + mll tot = 0; + for (int i = 1; i <= n; ++i) { + tot += comb(n - 1, i - 1) * dp[i] * fact[n - i]; + } + cout << fact[n] - tot << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-888g.cc b/src/bin/cf-888g.cc new file mode 100644 index 0000000..02f8b39 --- /dev/null +++ b/src/bin/cf-888g.cc @@ -0,0 +1,801 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) \ + __(); \ + __VA_ARGS__; \ + __() +#define __as_typeof(container) remove_reference::type +template +struct argument_type; +template +struct argument_type +{ + using type = U; +}; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template +pair> discretize(Iterator __first, Iterator __last) +{ + set st(__first, __last); + size_t N = 0; + map mp; + for (auto &&x : st) + mp[x] = ++N; + return {N, mp}; +} +template +pair> unordered_discretize(Iterator __first, Iterator __last) +{ + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto &&x : st) + mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template +istream &operator>>(istream &, pair &); +template +ostream &operator<<(ostream &, const pair &); +template +istream &operator>>(istream &, array &); +template +ostream &operator<<(ostream &, const array &); +template +decltype(auto) operator<<(std::basic_ostream &, const std::tuple &); +template +ostream &operator<<(ostream &, const vector &); +std::ostream &operator<<(std::ostream &, const int128 &); + +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 +istream &operator>>(istream &in, array &a) +{ + for (size_t i = 0; i < N; ++i) + in >> a[i]; + return in; +} +template +ostream &operator<<(ostream &out, const array &a) +{ + for (auto &&i : a) + out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream &os, const Tuple &t, std::index_sequence) +{ + using swallow = int[]; // guaranties left to right order + (void)swallow{0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)...}; +} +template +decltype(auto) operator<<(std::basic_ostream &os, const std::tuple &t) +{ + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template +ostream &operator<<(ostream &out, const vector &vec) +{ + for (auto &&i : vec) + out << i << ' '; + return out; +} +std::ostream &operator<<(std::ostream &dest, const int128 &value) +{ + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s(dest); + if (s) + { + uint128 tmp = value < 0 ? -value : value; + char buffer[128]; + char *d = std::end(buffer); + do + { + --d; + *d = "0123456789"[tmp % 10]; + tmp /= 10; + } while (tmp != 0); + if (value < 0) + { + --d; + *d = '-'; + } + int len = std::end(buffer) - d; + if (dest.rdbuf()->sputn(d, len) != len) + { + dest.setstate(std::ios_base::badbit); + } + } + return dest; +} +template +void __read(T &x) { cin >> x; } +template +void __read(T &x, U &...args) +{ + cin >> x; + __read(args...); +} +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto &x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x " = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a " = "; for (auto &&x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container &q) +{ + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container &q) +{ + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container &q) +{ + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) +{ + if (b == 0 and p != 0) + return 0; + if (p == 0) + return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) + return (int128(half) * half % mod) * b % mod; + else + return half * half % mod; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) +{ + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) + { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) + { + l = mid; + } + else + { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL &operator+=(const MLL &rhs) { return *this = *this + rhs; } + MLL &operator-=(const MLL &rhs) { return *this = *this - rhs; } + MLL &operator*=(const MLL &rhs) { return *this = *this * rhs; } + MLL &operator/=(const MLL &rhs) { return *this = *this / rhs; } + MLL &operator%=(const MLL &rhs) { return *this = *this % rhs; } +}; + +template +ostream &operator<<(ostream &out, const MLL &num) +{ + return out << num.val; +} + +template +istream &operator>>(istream &in, MLL &num) +{ + return in >> num.val; +} + +// miscancellous +template +bool chmax(T &lhs, const U &rhs) +{ + bool ret = lhs < rhs; + if (ret) + { + lhs = rhs; + } + return ret; +} +template +bool chmin(T &lhs, const U &rhs) +{ + bool ret = lhs > rhs; + if (ret) + { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto &&...val) noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ + { return func(std::forward(val)...); }) +#define expr(ret, ...) ([&](__VA_ARGS__) { return (ret); }) +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)) +namespace detail +{ + template + constexpr std::array + make_array(const T &value, std::index_sequence) + { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T &value) +{ + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() +{ +} + +// __attribute__((target("popcnt"))) +void solve() +{ + read(int, n); + readvec(int, a, n); + sort(a.begin(), a.end()); + ll res = 0; + { + auto dfs = [&] (auto dfs, int l, int r, int loc) -> void { + if (loc == -1 or l > r) return; + vector> trie(1); + auto insert = [&] (int val) { + int curr = 0; + for (int i = 31; ~i; --i) { + int bit = val >> i & 1; + if (not trie[curr][bit]) { + trie[curr][bit] = trie.size(); + trie.emplace_back(); + } + curr = trie[curr][bit]; + } + }; + auto query = [&] (int val) { + int curr = 0; + int res = 0; + for (int i = 31; ~i; --i) { + int bit = val >> i & 1; + if (not trie[curr][bit]) { + res xor_eq 1 << i; + curr = trie[curr][1 xor bit]; + } else { + curr = trie[curr][bit]; + } + } + return res; + }; + array, 2> has; + for (int i = l; i <= r; ++i) { + has[a[i] >> loc & 1].emplace_back(a[i]); + } + if (has[0].empty() or has[1].empty()) { + dfs(dfs, l, r, loc - 1); + } else { + for (auto&& x : has[0]) { + insert(x); + } + int curr = INF; + for (auto&& x : has[1]) { + chmin(curr, query(x)); + } + res += curr; + dfs(dfs, l, l + has[0].size() - 1, loc - 1); + dfs(dfs, l + has[0].size(), r, loc - 1); + } + }; + dfs(dfs, 0, n - 1, 31); + } + cout << res << '\n'; +} + +int main() +{ +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-891c.cc b/src/bin/cf-891c.cc new file mode 100644 index 0000000..52f366d --- /dev/null +++ b/src/bin/cf-891c.cc @@ -0,0 +1,674 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +class quick_union { +public: + size_t n; + vector c, sz; + vector> history; +public: + quick_union(size_t n) : n(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) return query(c[i]); + return c[i]; + } + void merge(size_t i, size_t j) { + if (connected(i, j)) { + history.emplace_back(n, n); + } else { + i = query(i), j = query(j); + if (sz[i] > sz[j]) swap(i, j); + history.emplace_back(i, j); + sz[j] += sz[i]; + c[i] = 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 rollback() { + auto [i, j] = popback(history); + if (i == n and j == n) return; + c[i] = i; + sz[j] -= sz[i]; + } +}; + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, m); + readvec((array), edges, m); + vector oc; + for (auto&& [u, v, w] : edges) { + oc.emplace_back(w); + } + sort(oc.begin(), oc.end()); + int t = unique(oc.begin(), oc.end()) - oc.begin(); + oc.resize(t); + auto get = [&] (int x) { return lower_bound(oc.begin(), oc.end(), x) - oc.begin(); }; + read(int, q); + vector> queries(q); + vector>>> bk(t); + vector res(q, 1); + for (int i = 0; i < q; ++i) { + read(int, m); + readvec(int, v, m); + transform(v.begin(), v.end(), v.begin(), expr(idx - 1, auto&& idx)); + sort_by_key(v.begin(), v.end(), expr(edges[idx][2], auto&& idx)); + vector>> grp; + for (int j = 0; j < m; ++j) { + if (grp.empty() or edges[v[j]][2] != grp.back().first) { + grp.emplace_back(edges[v[j]][2], vector { v[j] }); + } else { + grp.back().second.emplace_back(v[j]); + } + } + for (auto&& [j, vec] : grp) { + bk[get(j)].emplace_back(i, vec); + } + queries[i] = std::move(v); + } + vector idx(m); + iota(idx.begin(), idx.end(), 0); + sort_by_key(idx.begin(), idx.end(), expr(edges[i][2], auto&& i)); + int ptr = 0; + quick_union qu(n + 1); + for (int i = 0; i < t; ++i) { + for (auto&& [idx, vec] : bk[i]) { + int cnt = 0; + for (auto&& ei : vec) { + auto&& [u, v, w] = edges[ei]; + assert(w == oc[i]); + if (qu.connected(u, v)) { + res[idx] = 0; + break; + } + qu.merge(u, v); + cnt += 1; + } + while (cnt--) { + qu.rollback(); + } + } + int nw = ptr; + while (nw < m and edges[idx[nw]][2] == oc[i]) { + qu.merge(edges[idx[nw]][0], edges[idx[nw]][1]); + nw += 1; + } + // for (auto&& [idx, vec] : bk[i]) { + // if (vec.size() != nw - ptr) { + // res[idx] = 0; + // } + // } + ptr = nw; + } + for (auto&& x : res) { + cout << (x ? "YES" : "NO") << '\n'; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-893f.cc b/src/bin/cf-893f.cc new file mode 100644 index 0000000..5cad499 --- /dev/null +++ b/src/bin/cf-893f.cc @@ -0,0 +1,696 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template struct segtree { + using info_type = Addable_Info; + using size_type = size_t; + struct Node { + size_type lson, rson; + info_type info; + }; + vector d; + vector version_root; + size_type _max; + void _copy(size_type& virt) { + int o = virt; + virt = d.size(); + d.emplace_back(); + if (o != 0) d.back() = d[o]; + } + explicit segtree(size_type&& _max) : d(1), _max(_max - 1) { + version_root.emplace_back(0); + } + segtree(const vector& init) : d(1), _max(init.size() - 1) { + version_root.emplace_back(0); + auto dfs = [&] (auto dfs, size_type s, size_type t, size_type p) -> void { + if (s == t) { + d[p].info = init[s]; + return; + } + int m = s + t >> 1; + _copy(d[p].lson), _copy(d[p].rson); + dfs(dfs, s, m, d[p].lson); + dfs(dfs, m + 1, t, d[p].rson); + }; + dfs(dfs, 0, _max, version_root[0]); + } + void _set(size_type s, size_type t, size_type p, size_type x, const info_type& c) { + if (s == t) { + d[p].info = c; + return; + } + size_type m = s + (t - s >> 1); + if (x <= m) { + _copy(d[p].lson); + _set(s, m, d[p].lson, x, c); + } else { + _copy(d[p].rson); + _set(m + 1, t, d[p].rson, x, c); + } + d[p].info = d[d[p].lson].info + d[d[p].rson].info; + } + size_type _clone(size_type version) { + d.emplace_back(d[version_root[version]]); + version_root.emplace_back(d.size() - 1); + return version_root.size() - 1; + } + size_type set(size_type version, size_type loc, const info_type& c) { + size_type new_version = _clone(version); + _set(0, _max, version_root[new_version], loc, c); + return new_version; + } + info_type _range_query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (l <= s and t <= r) { + return d[p].info; + } + size_type m = s + (t - s >> 1); + info_type ret = {}; + if (l <= m and d[p].lson != 0) { + ret = ret + _range_query(s, m, d[p].lson, l, r); + } + if (r > m and d[p].rson != 0) { + ret = ret + _range_query(m + 1, t, d[p].rson, l, r); + } + return ret; + } + info_type range_query(size_type version, size_type l, size_type r) { + return _range_query(0, _max, version_root[version], l, r); + } + info_type query(size_type version, size_type loc) { + return range_query(version, loc, loc); + } +}; +struct Info { + int val = INF; +}; +Info operator+(const Info& lhs, const Info& rhs) { + return { min(lhs.val, rhs.val) }; +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, root); + readvec1(int, a, n); + adj(ch, n); + for (int i = 0; i < n - 1; ++i) { + read(int, u, v); + edge(ch, u, v); + } + vector dfn(n + 1); + vector sz(n + 1); + vector> layer(n + 1); + vector depth(n + 1); + { + int t = 0; + auto dfs = [&] (auto dfs, int v, int pa) -> void { + dfn[v] = t++; + sz[v] = 1; + depth[v] = depth[pa] + 1; + layer[depth[v]].emplace_back(v); + for (auto&& u : ch[v]) { + if (u == pa) continue; + dfs(dfs, u, v); + sz[v] += sz[u]; + } + }; + dfs(dfs, root, 0); + } + segtree tr(n); + vector version(n + 1); + int curr = 0; + for (int i = 1; i <= n; ++i) { + for (auto&& v : layer[i]) { + curr = tr.set(curr, dfn[v], { a[v] }); + } + version[i] = curr; + } + read(int, q); + int last = 0; + while (q--) { + read(int, p, q); + int x = (p + last) % n + 1; + int k = (q + last) % n; + last = tr.range_query(version[min(n, depth[x] + k)], dfn[x], dfn[x] + sz[x] - 1).val; + cout << last << '\n'; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-894d.cc b/src/bin/cf-894d.cc new file mode 100644 index 0000000..f1ea642 --- /dev/null +++ b/src/bin/cf-894d.cc @@ -0,0 +1,765 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#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 { + void apply(const Tag& rhs) { } +}; +struct Info { + ll val = 0; + int cnt = 0; + void apply(const Tag& rhs, size_t len) { } +}; +Info operator+(const Info &a, const Info &b) { + return { + .val = a.val + b.val, + .cnt = a.cnt + b.cnt, + }; +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, m); + vector> e(n + 1); + vector w(n + 1); + for (int i = 2; i <= n; ++i) { + read(int, x); + w[i] = x; + edgew(e, i, i / 2, x); + } + vector p(n + 1); + vector dfn(n + 1); + vector sz(n + 1); + { + int t = 0; + auto dfs = [&] (auto dfs, int v, int pa) -> void { + dfn[v] = t++; + sz[v] = 1; + for (auto&& [u, w] : e[v]) { + if (u == pa) continue; + p[u] = p[v] + w; + dfs(dfs, u, v); + sz[v] += sz[u]; + } + }; + dfs(dfs, 1, 0); + } + readvec(pii, q, m); + vector> queries; + vector ans; + int c = 0; + for (auto&& [v, d] : q) { + ans.emplace_back(); + queries.emplace_back(d + 2 * p[v] - p[v], v, c++); + int l = 1; + int u = v xor 1; + while (u > 1) { + ans.emplace_back(); + queries.emplace_back(d + 2 * p[u / 2] - p[v], u, c++); + u = u >> 1 xor 1; + l += 1; + } + } + sort(queries.begin(), queries.end()); + vector idx(n); + iota(idx.begin(), idx.end(), 1); + sort_by_key(idx.begin(), idx.end(), expr(p[v], int v)); + segtree tr(n); + int ptr = 0; + for (auto&& v : idx) { + while (ptr < queries.size() and get<0>(queries[ptr]) <= p[v]) { + auto [_, u, idx] = queries[ptr]; + ptr += 1; + if (u > n) continue; + Info r = tr.range_query(dfn[u], dfn[u] + sz[u] - 1); + ans[idx] = r; + } + tr.set(dfn[v], { + .val = p[v], + .cnt = 1, + }); + } + while (ptr < queries.size()) { + auto [_, u, idx] = queries[ptr]; + ptr += 1; + if (u > n) continue; + auto r = tr.range_query(dfn[u], dfn[u] + sz[u] - 1); + ans[idx] = r; + } + c = 0; + for (auto&& [v, d] : q) { + ll res = 0; + { + auto [val, cnt] = ans[c++]; + res += ll(1) * cnt * (d + p[v]) - val; + } + int l = 1; + int u = v xor 1; + while (u > 1) { + auto [val, cnt] = ans[c++]; + res += cnt * (d - p[v] + 2 * p[u / 2]) - val; + u = u >> 1 xor 1; + l += 1; + } + u = v / 2; + while (u != 0) { + if (p[v] - p[u] < d) { + res += d - p[v] + p[u]; + } + u >>= 1; + } + cout << res << '\n'; + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-894e.cc b/src/bin/cf-894e.cc new file mode 100644 index 0000000..a34d9af --- /dev/null +++ b/src/bin/cf-894e.cc @@ -0,0 +1,764 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#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; + } +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, m); + readvec((array), edges, m); + read(int, s); + vector scn; + { + adj(ch, n); + for (auto&& [u, v, w] : edges) { + Edge(ch, u, v); + } + scn = tarjan::scc(ch); + } + vector sum = { 0 }; + for (int i = 1; sum.back() <= 1e8; ++i) { + sum.emplace_back(ll(i + 1) * i / 2); + } + vector ps(sum.size()); + partial_sum(sum.begin(), sum.end(), ps.begin()); + int nn = *max_element(scn.begin(), scn.end()); + vector> e(nn + 1); + vector ind(nn + 1); + vector pw(nn + 1); + for (auto&& [u, v, w] : edges) { + if (scn[u] != scn[v]) { + Edgew(e, scn[u], scn[v], w); + } else { + int l = upper_bound(sum.begin(), sum.end(), w) - sum.begin() - 1; + pw[scn[v]] += ll(1) * w * (l + 1) - ps[l]; + } + } + { + vector vis(nn + 1); + auto dfs = [&] (auto dfs, int v) -> void { + if (vis[v]) return; + vis[v] = 1; + for (auto&& [u, w] : e[v]) { + ind[u] += 1; + dfs(dfs, u); + } + }; + dfs(dfs, scn[s]); + } + vector dp(nn + 1, -INFLL); + deque q = { scn[s] }; + dp[scn[s]] = 0; + while (q.size()) { + int v = popfront(q); + dp[v] += pw[v]; + for (auto&& [u, w] : e[v]) { + chmax(dp[u], dp[v] + w); + if (--ind[u] == 0) { + q.emplace_back(u); + } + } + } + cout << *max_element(dp.begin(), dp.end()) << '\n'; +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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-895e.cc b/src/bin/cf-895e.cc new file mode 100644 index 0000000..dcdbf3a --- /dev/null +++ b/src/bin/cf-895e.cc @@ -0,0 +1,706 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +#pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#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 { + ld mul = 1; + ld add = 0; + void apply(const Tag& rhs) { + add *= rhs.mul; + mul *= rhs.mul; + add += rhs.add; + } +}; +struct Info { + ld val = 0; + void apply(const Tag& rhs, size_t len) { + val = val * rhs.mul + len * rhs.add; + } +}; +Info operator+(const Info &a, const Info &b) { + return {a.val + b.val}; +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, q); + readvec(int, a, n); + segtree tr(n); + for (int i = 0; i < n; ++i) { + tr.set(i, { ld(a[i]) }); + } + cout << fixed << setprecision(50); + while (q--) { + read(int, type); + if (type == 1) { + read(int, l1, r1, l2, r2); + --l1, --r1, --l2, --r2; + ld left = tr.range_query(l1, r1).val; + ld right = tr.range_query(l2, r2).val; + tr.range_apply(l1, r1, { + .mul = ld(1) * (r1 - l1) / (r1 - l1 + 1), + .add = ld(1) / (r1 - l1 + 1) * right / (r2 - l2 + 1), + }); + tr.range_apply(l2, r2, { + .mul = ld(1) * (r2 - l2) / (r2 - l2 + 1), + .add = ld(1) / (r2 - l2 + 1) * left / (r1 - l1 + 1), + }); + } else { + read(int, l, r); + --l, --r; + cout << tr.range_query(l, r).val << '\n'; + } + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_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/lg-3919.cc b/src/bin/lg-3919.cc new file mode 100644 index 0000000..75b9100 --- /dev/null +++ b/src/bin/lg-3919.cc @@ -0,0 +1,672 @@ +// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2") +// #pragma GCC optimize("Ofast,unroll-loops") +/************* This code requires C++17. ***************/ + +#include +using namespace std; + +/* macro helpers */ +#define __NARGS(...) std::tuple_size::value +#define __DECOMPOSE_S(a, x) auto x = a; +#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a; +constexpr void __() {} +#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __() +#define __as_typeof(container) remove_reference::type +template struct argument_type; +template struct argument_type { using type = U; }; + +/* 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_64 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 adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) + +// add declarations to avoid cyclic dependency +template istream& operator>>(istream&, pair&); +template ostream& operator<<(ostream&, const pair&); +template istream& operator>>(istream&, array&); +template ostream& operator<<(ostream&, const array&); +template +decltype(auto) operator<<(std::basic_ostream&, const std::tuple&); +template ostream& operator<<(ostream&, const vector&); +std::ostream& operator<<(std::ostream&, const int128&); + +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 istream& operator>>(istream& in, array& a) { + for (size_t i = 0; i < N; ++i) in >> a[i]; + return in; +} +template ostream& operator<<(ostream& out, const array& a) { + for (auto&& i : a) out << i << ' '; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(t, ...) __AS_PROCEDURE(argument_type::type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(t, a, n) __AS_PROCEDURE(vector::type> a(n); for (auto& x : a) cin >> x;) +#define readvec1(t, a, n) __AS_PROCEDURE(vector::type> a((n) + 1); copy_n(ii::type>(cin), (n), a.begin() + 1);) +#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;) +#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +#define deb(...) debug(make_tuple(__VA_ARGS__)) + +/* pops */ +template +inline auto poptop(Container& q) { + auto ret = q.top(); + q.pop(); + return ret; +} +template +inline auto popback(Container& q) { + auto ret = q.back(); + q.pop_back(); + return ret; +} +template +inline auto popfront(Container& q) { + auto ret = q.front(); + q.pop_front(); + return ret; +} + +/* 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; +} + +// dynamic modulus +ll qpow(ll b, ll p, ll mod) { + if (b == 0 and p != 0) return 0; + if (p == 0) return 1; + ll half = qpow(b, p / 2, mod); + if (p % 2 == 1) return (int128(half) * half % mod) * b % mod; + else return half * half % mod; +} + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +// Accurately find `i` 'th root of `n` (taking the floor) +inline ll root(ll n, ll i) { + ll l = 0, r = pow(LLONG_MAX, ld(1) / i); + while (l < r) { + ll mid = l + r + 1 >> 1; + if (qpow(mid, i) <= n) { + l = mid; + } else { + r = mid - 1; + } + } + return l; +} +#pragma GCC diagnostic pop + + +#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)]) +#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)]) + +__attribute__((target("lzcnt"))) +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +template +T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); } + +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; } + MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; } + MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; } + MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; } + MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; } + MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; } +}; + +template +ostream& operator<<(ostream& out, const MLL& num) { + return out << num.val; +} + +template +istream& operator>>(istream& in, MLL& num) { + return in >> num.val; +} + +// miscancellous +template +bool chmax(T& lhs, const U& rhs) { + bool ret = lhs < rhs; + if (ret) { + lhs = rhs; + } + return ret; +} +template +bool chmin(T& lhs, const U& rhs) { + bool ret = lhs > rhs; + if (ret) { + lhs = rhs; + } + return ret; +} + +#define functor(func) ([&](auto&&... val) \ +noexcept(noexcept(func(std::forward(val)...))) -> decltype(auto) \ +{return func(std::forward(val)...);}) +#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); }) +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)) +namespace detail { + template + constexpr std::array + make_array(const T& value, std::index_sequence) { + return {{(static_cast(Is), value)...}}; + } +} + +template +constexpr std::array __initarray(const T& value) { + return detail::make_array(value, std::make_index_sequence()); +} +/*******************************************************/ + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 +// #define TOT_TEST_CASE 10000 + +void dump() {} + +void dump_ignore() {} + +void prep() { +} + +template struct segtree { + using info_type = Addable_Info; + using size_type = size_t; + struct Node { + size_type lson, rson; + info_type info; + }; + vector d; + vector version_root; + size_type _max; + + void _copy(size_type& virt) { + int o = virt; + virt = d.size(); + d.emplace_back(); + if (o != 0) d.back() = d[o]; + } + explicit segtree(size_type&& _max) : d(1), _max(_max - 1) { + version_root.emplace_back(0); + } + segtree(const vector& init) : d(1), _max(init.size() - 1) { + version_root.emplace_back(0); + auto dfs = [&] (auto dfs, size_type s, size_type t, size_type p) -> void { + if (s == t) { + d[p].info = init[s]; + return; + } + int m = s + t >> 1; + _copy(d[p].lson), _copy(d[p].rson); + dfs(dfs, s, m, d[p].lson); + dfs(dfs, m + 1, t, d[p].rson); + }; + dfs(dfs, 0, _max, version_root[0]); + } + void _set(size_type s, size_type t, size_type p, size_type x, const info_type& c) { + if (s == t) { + d[p].info = c; + return; + } + size_type m = s + (t - s >> 1); + if (x <= m) { + _copy(d[p].lson); + _set(s, m, d[p].lson, x, c); + } else { + _copy(d[p].rson); + _set(m + 1, t, d[p].rson, x, c); + } + } + size_type _clone(size_type version) { + d.emplace_back(d[version_root[version]]); + version_root.emplace_back(d.size() - 1); + return version_root.size() - 1; + } + size_type set(size_type version, size_type loc, const info_type& c) { + size_type new_version = _clone(version); + _set(0, _max, version_root[new_version], loc, c); + return new_version; + } + info_type _range_query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (l <= s and t <= r) { + return d[p].info; + } + size_type m = s + (t - s >> 1); + info_type ret = {}; + if (l <= m and d[p].lson != 0) { + ret = ret + _range_query(s, m, d[p].lson, l, r); + } + if (r > m and d[p].rson != 0) { + ret = ret + _range_query(m + 1, t, d[p].rson, l, r); + } + return ret; + } + info_type range_query(size_type version, size_type l, size_type r) { + return _range_query(0, _max, version_root[version], l, r); + } + info_type query(size_type version, size_type loc) { + return range_query(version, loc, loc); + } +}; + +struct Info { + int val; +}; + +Info operator+(const Info& lhs, const Info& rhs) { + return { lhs.val + rhs.val }; +} + +// __attribute__((target("popcnt"))) +void solve() { + read(int, n, m); + readvec(int, a, n); + segtree tr(a); + vector ver(m + 1); + for (int i = 0; i < n; ++i) { + ver[0] = tr.set(ver[0], i, { a[i] }); + } + for (int i = 1; i <= m; ++i) { + read(int, v, op, idx); + --idx; + if (op == 1) { + read(int, val); + ver[i] = tr.set(ver[v], idx, val); + } else { + cout << tr.query(ver[v], idx) << '\n'; + ver[i] = ver[v]; + } + } +} + +int main() { +#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__) + static_assert(false, "incompatible compiler variant detected."); +#endif + untie; + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t != (TOT_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/std.in b/src/bin/std.in index 53c0ef3..8193abe 100644 --- a/src/bin/std.in +++ b/src/bin/std.in @@ -1,6 +1,2 @@ -3 -1000 1000 1000 1 -*** -*** -*** -*** +4 +1 2 3 4 diff --git a/src/bin/test.cc b/src/bin/test.cc index a6c3aae..e98d7c7 100644 --- a/src/bin/test.cc +++ b/src/bin/test.cc @@ -537,7 +537,6 @@ void prep() { // __attribute__((target("popcnt"))) void solve() { - int a = 1 + 2 >> 2; } int main() { diff --git a/src/bin/test.py b/src/bin/test.py index ec9b6f1..9896946 100644 --- a/src/bin/test.py +++ b/src/bin/test.py @@ -8,7 +8,7 @@ import io PRIME = 998_244_353 if __name__ == '__main__': - N = 1000 - print(N) - print(*([1000] * 4)) - print(*(''.join((choice(('*', '.')) for _ in range(N))) for _ in range(4))) + N = 10 ** 6 + print(N, N) + print(*(f'{randint(1, N)} {randint(1, N)} {randint(0, 10 ** 8)}' for _ in range(N))) + print(randint(1, N))