diff --git a/src/bin/a.out b/src/bin/a.out index 828b8be..197738f 100755 Binary files a/src/bin/a.out and b/src/bin/a.out differ diff --git a/src/bin/cf-1788e.cc b/src/bin/cf-1788e.cc new file mode 100644 index 0000000..d4eb4c8 --- /dev/null +++ b/src/bin/cf-1788e.cc @@ -0,0 +1,491 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +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); + d[p] = d[p * 2] + d[p * 2 + 1]; + } + + 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 { + int val = INT_MIN; + void apply(const Tag& rhs) { + if (rhs.val != -1) + val = rhs.val; + } +}; + +struct Info { + int val = INT_MIN; + void apply(const Tag& rhs, size_t len) { + val = max(val, rhs.val); + } +}; + +Info operator+(const Info &a, const Info &b) { + return {max(a.val, b.val)}; +} + +void solve() { + read(int, n); + readvec(int, a, n); + vector ps(n + 1); + for (int i = 1; i <= n; ++i) { + ps[i] = ps[i - 1] + a[i - 1]; + } + set st(ps.begin(), ps.end()); + unordered_map mp; + int N = 0; + for (auto&& x : st) mp[x] = ++N; + // for (int i = 0; i <= n; ++i) { + // cerr << mp[ps[i]] << " \n"[i == n]; + // } + // for (auto&& [x, y] : mp) cerr << x << ' ' << y << '\n'; + segtree dp(N + 1); + dp.set(mp[0], {0}); + int prev = 0; + for (int i = 1; i <= n; ++i) { + int curr = max(prev, dp.range_query(0, mp[ps[i]]).val + i); + // debug(curr); + dp.apply(mp[ps[i]], { curr - i });; + prev = curr; + } + // for (auto&& x : dp.serialize()) cerr << x.val << ' '; + // cerr << endl; + cout << prev << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1789d.cc b/src/bin/cf-1789d.cc new file mode 100644 index 0000000..418546e --- /dev/null +++ b/src/bin/cf-1789d.cc @@ -0,0 +1,439 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +void dump() {} + +void dump_ignore() {} + +void prep() {} + +void solve() { + read(int, n); + vector a(n), b(n); + int first_one = -1; + for (int i = 0; i < n; ++i) { + read(char, c); + a[i] = c - 48; + if (first_one == -1 and a[i]) { + first_one = i; + } + } + for (int i = 0; i < n; ++i) { + read(char, c); + b[i] = c - 48; + } + vector seq; + auto apply = [&] (int op) { + seq.emplace_back(op); + vector curr(n); + for (int j = 0; j < n; ++j) { + if (j + op >= 0 and j + op < n) { + curr[j] = a[j + op]; + } + } + for (int j = 0; j < n; ++j) { + a[j] ^= curr[j]; + } + }; + if (first_one != -1) { + int start = 0; + while (start < n) { + if (a[start] or b[start]) { + break; + } + ++start; + } + if (start != n) { + if (a[start] == 0 and b[start] == 1) { + int next_one = -1; + for (int i = start + 1; i < n; ++i) { + if (a[i] == 1) { + next_one = i; + break; + } + } + if (next_one != -1) { + apply(next_one - start); + first_one = start; + } else { + cout << -1 << '\n'; + return; + } + } else { + first_one = start; + } + } else { + cout << 0 << '\n'; + return; + } + for (int i = start + 1; i < n; ++i) { + if (a[i] != b[i]) { + apply(first_one - i); + } + } + while (first_one != -1 and a[first_one] != b[first_one]) { + int last_one = -1; + for (int i = n - 1; i > first_one; --i) { + if (a[i]) { + last_one = i; + break; + } + } + if (last_one != -1) { + apply(last_one - first_one); + int new_first_one = -1; + for (int i = first_one - 1; i >= 0; --i) { + if (a[i]) { + new_first_one = i; + break; + } + } + first_one = new_first_one; + } else { + cout << -1 << '\n'; + return; + } + } + } + // debug(a), debug(b);; + for (int i = 0; i < n; ++i) { + if (a[i] != b[i]) { + cout << -1 << '\n'; + return; + } + } + cout << seq.size() << '\n'; + if (seq.size()) { + putvec(seq); + } +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1799d2.cc b/src/bin/cf-1799d2.cc new file mode 100644 index 0000000..107be4e --- /dev/null +++ b/src/bin/cf-1799d2.cc @@ -0,0 +1,504 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +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); + d[p] = d[p * 2] + d[p * 2 + 1]; + } + + void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) { + if (l <= s && t <= r) { + d[p].apply(c, t - s + 1); + b[p].apply(c); + return; + } + size_type m = s + (t - s >> 1); + push(p, m - s + 1, t - m); + if (l <= m) range_apply(s, m, p * 2, l, r, c); + if (r > m) range_apply(m + 1, t, p * 2 + 1, l, r, c); + pull(p); + } + + info_type range_query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (l <= s && t <= r) { + return d[p]; + } + size_type m = s + (t - s >> 1); + info_type res = {}; + push(p, m - s + 1, t - m); + if (l <= m) res = res + range_query(s, m, p * 2, l, r); + if (r > m) res = res + range_query(m + 1, t, p * 2 + 1, l, r); + return res; + } + + void build(const Sequence& a, size_type s, size_type t, size_type p) { + if (s == t) { + d[p] = a[s]; + return; + } + int m = s + (t - s >> 1); + build(a, s, m, p * 2); + build(a, m + 1, t, p * 2 + 1); + pull(p); + } +public: + segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {} + segtree(const Sequence& a) : segtree(a.size()) { + build(a, {}, _max, 1); + } + + void set(size_type i, const info_type& c) { + set({}, _max, 1, i, c); + } + + void range_apply(size_type l, size_type r, const tag_type& c) { + range_apply({}, _max, 1, l, r, c); + } + + void apply(size_type i, const tag_type& c) { + range_apply(i, i, c); + } + + info_type range_query(size_type l, size_type r) { + return range_query({}, _max, 1, l, r); + } + + info_type query(size_type i) { + return range_query(i, i); + } + + Sequence serialize() { + Sequence res = {}; + for (size_type i = 0; i <= _max; ++i) { + res.push_back(query(i)); + } + return res; + } + + const vector& get_d() { + return d; + } +}; + +struct Tag { + ll val = 0; + void apply(const Tag& rhs) { + val += rhs.val; + } +}; + +struct Info { + ll val = LLONG_MAX; + void apply(const Tag& rhs, size_t len) { + if (rhs.val < 0 or val <= LLONG_MAX - rhs.val) { + val += rhs.val; + } else { + val = LLONG_MAX; + } + } +}; + +Info operator+(const Info &a, const Info &b) { + return {min(a.val, b.val)}; +} + +void solve() { + read(int, n, k); + readvec(int, idx, n); + readvec(int, a, k); + readvec(int, b, k); + segtree row(k + 1), col(k + 1); + // vector row_enable(k + 1), col_enable(k + 1); + row.set(0, {0}); + col.set(0, {0}); + int prev = 0; + for (auto&& i : idx) { + if (i == prev) { + row.range_apply(0, k, {b[i - 1]}); + col.range_apply(0, k, {b[i - 1]}); + } else { + ll row_query = row.query(i).val; + ll col_query = col.query(i).val; + ll prev_row = min(row.range_query(0, k).val + a[i - 1], row_query != LLONG_MAX ? row_query + b[i - 1] : LLONG_MAX); + ll prev_col = min(col.range_query(0, k).val + a[i - 1], col_query != LLONG_MAX ? col_query + b[i - 1] : LLONG_MAX); + row.range_apply(0, k, {a[i - 1]}); + col.range_apply(0, k, {a[i - 1]}); + row.apply(i, {b[i - 1] - a[i - 1]}); + col.apply(i, {b[i - 1] - a[i - 1]}); + row.set(prev, {prev_col}); + col.set(prev, {prev_row}); + // for (auto&& x : row.serialize()) { + // cerr << x.val << ' ';; + // } + // cerr << endl; + // for (auto&& x : col.serialize()) { + // cerr << x.val << ' ';; + // } + // cerr << endl; + } + prev = i; + } + cout << min(row.range_query(0, k).val, col.range_query(0, k).val) << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1800f.cc b/src/bin/cf-1800f.cc new file mode 100644 index 0000000..e42a2d3 --- /dev/null +++ b/src/bin/cf-1800f.cc @@ -0,0 +1,376 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +uniform_int_distribution dist(PRIME); +const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd); +struct array_hash { + template + size_t operator()(const Sequence& arr) const { + size_t pw1 = 1, pw2 = 1; + size_t res1 = 0, res2 = 0; + for (auto&& x : arr) { + res1 = (res1 + x * pw1) % __array_hash_mdl1; + res2 = (res2 + x * pw2) % __array_hash_mdl2; + pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1; + pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2; + } + return res1 + res2; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +void dump() {} + +void dump_ignore() {} + +void prep() {} + +unordered_map st[26]; + +void solve() { + read(int, n); + readvec(string, a, n); + ll res = 0; + for (auto&& s : a) { + int not_mask = (1 << 26) - 1; + int curr = 0; + for (auto&& c : s) { + int x = c - 'a'; + if ((not_mask >> x) & 1) { + not_mask ^= 1 << x; + } + curr ^= 1 << x; + } + int other = 0; + for (int i = 0; i < 26; ++i) { + if ((not_mask >> i) & 1) { + other |= 1 << i; + } else { + other |= (1 << i) ^ (curr & (1 << i)); + } + } + for (int i = 0; i < 26; ++i) { + if ((not_mask >> i) & 1) { + res += st[i][other]; + } + } + for (int i = 0; i < 26; ++i) { + if ((not_mask >> i) & 1) { + st[i][curr | 1 << i] += 1; + } + } + } + cout << res << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1801c.cc b/src/bin/cf-1801c.cc new file mode 100644 index 0000000..7801993 --- /dev/null +++ b/src/bin/cf-1801c.cc @@ -0,0 +1,497 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +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); + d[p] = d[p * 2] + d[p * 2 + 1]; + } + + 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 { + int val = -1; + void apply(const Tag& rhs) { + if (rhs.val != -1) + val = rhs.val; + } +}; + +struct Info { + int val = 0; + void apply(const Tag& rhs, size_t len) { + if (rhs.val != -1) + val = rhs.val * len; + } +}; + +Info operator+(const Info &a, const Info &b) { + return {max(a.val, b.val)}; +} + +void solve() { + read(int, n); + vector>> data; + for (int i = 0; i < n; ++i) { + vector curr; + read(int, k); + while (k--) { + read(int, x); + curr.emplace_back(x); + } + data.emplace_back(*max_element(curr.begin(), curr.end()), curr); + } + sort(data.begin(), data.end()); + segtree dp(n + 1); + for (int i = 1; i <= n; ++i) { + auto&& curr = data[i - 1].second; + int k = curr.size(); + vector st; + for (int j = k - 1; ~j; --j) { + int curr_res = 0; + while (st.size() and st.back().first <= curr[j]) { + st.pop_back(); + } + // binary search for max[t] < a[j], select max(dp[t]) + { + int l = 0, r = i - 1; + while (l < r) { + int mid = l + r + 1 >> 1; + if (data[mid].first >= curr[j]) { + r = mid - 1; + } else { + l = mid; + } + } + if (data[l].first < curr[j]) { + // debug(i), debug(j), debug(l), debug(dp.range_query(0, l).val), debug(st.size()); + curr_res = dp.range_query(1, l + 1).val + int(st.size()) + 1; + } else { + curr_res = int(st.size()) + 1; + } + } + st.emplace_back(curr[j], curr_res); + } + dp.set(i, { max_element(st.begin(), st.end(), [] (const pii& a, const pii& b) { return a.second < b.second; })->second }); + // for (auto&& x : dp.serialize()) { + // cerr << x.val << ' '; + // } + } + cout << dp.range_query(0, n).val << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1801d.cc b/src/bin/cf-1801d.cc new file mode 100644 index 0000000..56f34c9 --- /dev/null +++ b/src/bin/cf-1801d.cc @@ -0,0 +1,364 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +// #define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +void dump() {} + +void dump_ignore() {} + +void prep() {} + +void solve() { + read(int, n, m, p); + vector> e(n + 1); + vector w(n + 1); + for (int i = 1; i <= n; ++i) cin >> w[i]; + while (m--) { + read(int, u, v, s); + e[u].emplace_back(v, s); + } + vector res(n + 1, {INFLL, 0}); + res[1] = {0, p}; + vector idx(n); + iota(idx.begin(), idx.end(), 1); + sort(idx.begin(), idx.end(), [&] (int i, int j) { return w[i] < w[j]; }); + for (auto&& i : idx) { + auto [curr_times, curr_bal] = res[i]; + priority_queue, greater<>> pq; + vector vis(n + 1); + vector dis(n + 1, INFLL); + pq.emplace(0, i); + while (pq.size()) { + poptop(pq, d, v); + continue_or(vis[v], 1); + for (auto&& [u, w] : e[v]) { + if (d + w < dis[u]) { + dis[u] = d + w; + pq.emplace(dis[u], u); + } + } + } + for (int j = 1; j <= n; ++j) { + if (dis[j] == INFLL) continue; + ll new_times = (max(ll(0), dis[j] - curr_bal) + w[i] - 1) / w[i]; + ll times = curr_times + new_times; + ll bal = curr_bal + new_times * w[i] - dis[j]; + if (times < res[j].first or times == res[j].first and bal > res[j].second) { + res[j] = {times, bal}; + } + } + } + cout << (res[n].first == INFLL ? -1 : res[n].first) << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1806e.cc b/src/bin/cf-1806e.cc new file mode 100644 index 0000000..07035a1 --- /dev/null +++ b/src/bin/cf-1806e.cc @@ -0,0 +1,346 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +void dump() {} + +void dump_ignore() {} + +void prep() {} + +void solve() { + read(int, n, q); + unordered_map dp; + vector father(n + 1); + vector a(n + 1); + for (int i = 1; i <= n; ++i) { + cin >> a[i]; + } + for (int i = 2; i <= n; ++i) { + cin >> father[i]; + } + auto dfs = [&] (auto dfs, int u, int v) -> ll { + if (u == 0 and v == 0) { + return 0; + } + if (not dp.count({u, v})) dp[{u, v}] = a[u] * a[v] + dfs(dfs, father[u], father[v]); + return dp[{u, v}]; + }; + while (q--) { + read(int, u, v); + ll ans = dfs(dfs, u, v); + cout << ans << '\n'; + } +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1808d.cc b/src/bin/cf-1808d.cc new file mode 100644 index 0000000..37119bb --- /dev/null +++ b/src/bin/cf-1808d.cc @@ -0,0 +1,387 @@ +#ifdef ONLINE_JUDGE +#pragma GCC optimize("Ofast") +#endif +///////////////////////////////////////////////////////// +/** + * Useful Macros + * by subcrip + * (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) decltype(container)::value_type + +/* type aliases */ +#if LONG_LONG_MAX != INT64_MAX +using ll = int64_t; +using ull = uint64_t; +#else +using ll = long long; +using ull = unsigned long long; +#endif +using int128 = __int128_t; +using uint128 = __uint128_t; +using pii = pair; +using pil = pair; +using pli = pair; +using pll = pair; + +/* constants */ +constexpr int INF = 0x3f3f3f3f; +constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL; +constexpr ll MDL = 1e9 + 7; +constexpr ll PRIME = 998'244'353; +constexpr ll MDL1 = 8784491; +constexpr ll MDL2 = PRIME; +constexpr int128 INT128_MAX = numeric_limits::max(); +constexpr uint128 UINT128_MAX = numeric_limits::max(); +constexpr int128 INT128_MIN = numeric_limits::min(); +constexpr uint128 UINT128_MIN = numeric_limits::min(); + +/* random */ + +mt19937 rd(chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count()); + +/* bit-wise operations */ +#define lowbit(x) ((x) & -(x)) +#define popcount(x) (__builtin_popcountll(ll(x))) +#define parity(x) (__builtin_parityll(ll(x))) +#define msp(x) (63LL - __builtin_clzll(ll(x))) +#define lsp(x) (__builtin_ctzll(ll(x))) + +/* arithmetic operations */ +#define mod(x, y) ((((x) % (y)) + (y)) % (y)) + +/* fast pairs */ +#define upair ull +#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1))) +#define u1(p) ((p) >> 32) +#define u2(p) ((p) & ((1ULL << 32) - 1)) +#define ult std::less +#define ugt std::greater + +#define ipair ull +#define imake(x, y) (umake(x, y)) +#define i1(p) (int(u1(ll(p)))) +#define i2(p) (ll(u2(p) << 32) >> 32) +struct ilt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) < i2(b); + else return i1(a) < i1(b); + } +}; +struct igt { + bool operator()(const ipair& a, const ipair& b) const { + if (i1(a) == i1(b)) return i2(a) > i2(b); + else return i1(a) > i1(b); + } +}; + +/* conditions */ +#define loop while (1) +#define if_or(var, val) if (!(var == val)) var = val; else +#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;) +#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;) + +/* hash */ +struct safe_hash { + // https://codeforces.com/blog/entry/62393 + static uint64_t splitmix64(uint64_t x) { + // http://xorshift.di.unimi.it/splitmix64.c + x += 0x9e3779b97f4a7c15; + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + return x ^ (x >> 31); + } + + size_t operator()(uint64_t x) const { + static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); + return splitmix64(x + FIXED_RANDOM); + } +}; + +struct pair_hash { + template + size_t operator()(const pair& a) const { + auto hash1 = safe_hash()(a.first); + auto hash2 = safe_hash()(a.second); + if (hash1 != hash2) { + return hash1 ^ hash2; + } + return hash1; + } +}; + +/* build data structures */ +#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];) +#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];) +#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);) +#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};) +#define adj(ch, n) __AS_PROCEDURE(vector> ch((n) + 1);) +#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);) +#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);) +template pair> discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} +template pair> unordered_discretize(Iterator __first, Iterator __last) { + set st(__first, __last); + size_t N = 0; + unordered_map mp; + for (auto&& x : st) mp[x] = ++N; + return {N, mp}; +} + +/* io */ +#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL)) +template void __read(T& x) { cin >> x; } +template void __read(T& x, U&... args) { cin >> x; __read(args...); } +#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);) +#define readvec(type, a, n) __AS_PROCEDURE(vector a(n); for (int i = 0; i < (n); ++i) cin >> a[i];) +#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;) +#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;) +#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;) +template ostream& operator<<(ostream& out, const pair& p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} +template +void print_tuple_impl(std::basic_ostream& os, const Tuple& t, std::index_sequence) { + using swallow = int[]; // guaranties left to right order + (void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get(t)), 0)... }; +} +template +decltype(auto) operator<<(std::basic_ostream& os, const std::tuple& t) { + os << "{"; + print_tuple_impl(os, t, std::index_sequence_for{}); + return os << "}"; +} +template ostream& operator<<(ostream& out, const vector& vec) { + for (auto&& i : vec) out << i << ' '; + return out; +} +std::ostream& operator<<(std::ostream& dest, const int128& value) { + // https://stackoverflow.com/a/25115163/23881100 + std::ostream::sentry s( dest ); + if ( s ) { + uint128 tmp = value < 0 ? -value : value; + char buffer[ 128 ]; + char* d = std::end( buffer ); + do { + -- d; + *d = "0123456789"[ tmp % 10 ]; + tmp /= 10; + } while ( tmp != 0 ); + if ( value < 0 ) { + -- d; + *d = '-'; + } + int len = std::end( buffer ) - d; + if ( dest.rdbuf()->sputn( d, len ) != len ) { + dest.setstate( std::ios_base::badbit ); + } + } + return dest; +} + +/* pops */ +#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();) +#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();) +#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();) + +/* math */ +constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); } + +void __exgcd(ll a, ll b, ll& x, ll& y) { + if (b == 0) { + x = 1, y = 0; + return; + } + __exgcd(b, a % b, y, x); + y -= a / b * x; +} + +ll inverse(ll a, ll b) { + ll x, y; + __exgcd(a, b, x, y); + return mod(x, b); +} + +vector> decompose(ll x) { + 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; +} + +/* 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; +} +///////////////////////////////////////////////////////// + +#define SINGLE_TEST_CASE +// #define DUMP_TEST_CASE 7219 + +void dump() {} + +void dump_ignore() {} + +void prep() {} + +void solve() { + read(int, n, k); + readvec(int, a, n); + array cnt {}; + int j = 0; + int l = 2; // [j, l) + ll res = 0; + cnt[a[j]] = 1; + for (int i = 0; i < n; i += 2) { + while (j < i or i - (k - (j - i + 1)) / 2 < 0) { + cnt[a[j]] -= 1; + j += 2; + } + while (j - 2 >= i and i - (k - (j - 2 - i + 1)) / 2 >= 0) { + j -= 2; + cnt[a[j]] += 1; + } + while (l < n and l - i + 1 <= k and (l <= j or l + (k - (l - i + 1)) / 2 < n)) { + cnt[a[l]] += 1; + l += 2; + } + while (l - 2 - i + 1 > k or (l - 2 > j and l - 2 + (k - (l - 2 - i + 1)) / 2 >= n)) { + l -= 2; + cnt[a[l]] -= 1; + } + if (l <= j) { + ;; + } else { + // debug(i), debug(j), debug(l); + // debug((l - j) / 2 - cnt[a[i]]); + res += (l - j) / 2 - cnt[a[i]]; + } + } + if (n == 1) goto fi; + j = 1, l = 3; + cnt.fill(0); + cnt[a[j]] = 1; + for (int i = 1; i < n; i += 2) { + while (j < i or i - (k - (j - i + 1)) / 2 < 0) { + cnt[a[j]] -= 1; + j += 2; + } + while (j - 2 >= i and i - (k - (j - 2 - i + 1)) / 2 >= 0) { + j -= 2; + cnt[a[j]] += 1; + } + while (l < n and l - i + 1 <= k and (l <= j or l + (k - (l - i + 1)) / 2 < n)) { + cnt[a[l]] += 1; + l += 2; + } + while (l - 2 - i + 1 > k or (l - 2 > j and l - 2 + (k - (l - 2 - i + 1)) / 2 >= n)) { + l -= 2; + cnt[a[l]] -= 1; + } + if (l <= j) { + ;; + } else { + // debug(i), debug(j), debug(l); + // debug((l - j) / 2 - cnt[a[i]]); + res += (l - j) / 2 - cnt[a[i]]; + } + } +fi: + cout << res << '\n'; +} + +int main() { +#if __cplusplus < 201703L || defined(_MSC_VER) && !defined(__clang__) + assert(false && "incompatible compiler variant detected."); +#endif + untie, cout.tie(NULL); + prep(); +#ifdef SINGLE_TEST_CASE + solve(); +#else + read(int, t); + for (int i = 0; i < t; ++i) { +#ifdef DUMP_TEST_CASE + if (t < (DUMP_TEST_CASE)) { + solve(); + } else if (i + 1 == (DUMP_TEST_CASE)) { + dump(); + } else { + dump_ignore(); + } +#else + solve(); +#endif + } +#endif +} diff --git a/src/bin/cf-1810e.cc b/src/bin/cf-1810e.cc index 4a136a8..f82dd67 100644 --- a/src/bin/cf-1810e.cc +++ b/src/bin/cf-1810e.cc @@ -286,7 +286,7 @@ int period(string s) { // find the length of shortest recurring period ///////////////////////////////////////////////////////// // #define SINGLE_TEST_CASE -// #define DUMP_TEST_CASE 7219 +// #define DUMP_TEST_CASE 1431 void dump() {} @@ -309,6 +309,7 @@ public: } void merge(size_t i, size_t j) { + if (connected(i, j)) return; sz[query(j)] += sz[query(i)]; c[query(i)] = query(j); } @@ -324,36 +325,44 @@ public: void solve() { read(int, n, m); - adj(cand, n); + adj(ch, n); vector a(n + 1); for (int i = 1; i <= n; ++i) { cin >> a[i]; } while (m--) { read(int, u, v); - edge(cand, u, v); + edge(ch, u, v); } vector idx(n + 1); quick_union qu(n + 1); iota(idx.begin(), idx.end(), 0); sort(idx.begin() + 1, idx.end(), [&] (int u, int v) { return a[u] < a[v]; }); + vector enable(n + 1); + for (int i = 1; i <= n; ++i) { + for (auto&& j : ch[i]) { + if (a[i] == a[j]) { + qu.merge(i, j); + } + } + } for (int t = 1; t <= n; ++t) { int v = idx[t]; int rest = a[v]; int mx = 0; // debug(v), debug(rest); - for (auto&& u : cand[v]) { - if (a[u] > rest or qu.query_size(u) == 1 and a[u]) { + for (auto&& u : ch[v]) { + if (not enable[qu.query(u)]) { continue; } mx = max(mx, int(qu.query_size(u))); } if (mx >= rest) { - for (auto&& u : cand[v]) { - if (a[u] > rest or qu.connected(u, v)) { - continue; - } - // debug(curr_sz), debug(my_sz); + enable[qu.query(v)] = 1; + } + for (auto&& u : ch[v]) { + if (a[u] < rest) { + enable[qu.query(u)] = enable[qu.query(v)]; qu.merge(v, u); } } @@ -361,9 +370,8 @@ void solve() { } int mx = 0; for (int i = 1; i <= n; ++i) { - int sz = qu.query_size(i); - if (not (sz == 1 and a[i])) { - mx = max(mx, sz); + if (enable[qu.query(i)]) { + mx = max(mx, int( qu.query_size(i) )); } } if (mx == n) { diff --git a/src/bin/ctext_out.cc b/src/bin/ctext_out.cc index 4a136a8..d4eb4c8 100644 --- a/src/bin/ctext_out.cc +++ b/src/bin/ctext_out.cc @@ -120,6 +120,23 @@ struct pair_hash { } }; +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 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];) @@ -285,7 +302,7 @@ int period(string s) { // find the length of shortest recurring period } ///////////////////////////////////////////////////////// -// #define SINGLE_TEST_CASE +#define SINGLE_TEST_CASE // #define DUMP_TEST_CASE 7219 void dump() {} @@ -294,83 +311,157 @@ void dump_ignore() {} void prep() {} -class quick_union { +template> class segtree { private: - vector c, sz; + 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); + d[p] = d[p * 2] + d[p * 2 + 1]; + } + + 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: - quick_union(size_t n) : c(n), sz(n) { - iota(c.begin(), c.end(), 0); - sz.assign(n, 1); - } - - size_t query(size_t i) { - if (c[i] != i) c[i] = query(c[i]); - return c[i]; - } - - void merge(size_t i, size_t j) { - sz[query(j)] += sz[query(i)]; - c[query(i)] = query(j); + segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {} + segtree(const Sequence& a) : segtree(a.size()) { + build(a, {}, _max, 1); } - bool connected(size_t i, size_t j) { - return query(i) == query(j); + 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); } - size_t query_size(size_t i) { - return sz[query(i)]; + 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 { + int val = INT_MIN; + void apply(const Tag& rhs) { + if (rhs.val != -1) + val = rhs.val; + } +}; + +struct Info { + int val = INT_MIN; + void apply(const Tag& rhs, size_t len) { + val = max(val, rhs.val); + } +}; + +Info operator+(const Info &a, const Info &b) { + return {max(a.val, b.val)}; +} + void solve() { - read(int, n, m); - adj(cand, n); - vector a(n + 1); + read(int, n); + readvec(int, a, n); + vector ps(n + 1); for (int i = 1; i <= n; ++i) { - cin >> a[i]; + ps[i] = ps[i - 1] + a[i - 1]; } - while (m--) { - read(int, u, v); - edge(cand, u, v); - } - vector idx(n + 1); - quick_union qu(n + 1); - iota(idx.begin(), idx.end(), 0); - sort(idx.begin() + 1, idx.end(), [&] (int u, int v) { return a[u] < a[v]; }); - for (int t = 1; t <= n; ++t) { - int v = idx[t]; - int rest = a[v]; - int mx = 0; - // debug(v), debug(rest); - for (auto&& u : cand[v]) { - if (a[u] > rest or qu.query_size(u) == 1 and a[u]) { - continue; - } - mx = max(mx, int(qu.query_size(u))); - } - if (mx >= rest) { - for (auto&& u : cand[v]) { - if (a[u] > rest or qu.connected(u, v)) { - continue; - } - // debug(curr_sz), debug(my_sz); - qu.merge(v, u); - } - } - // debug(sz); - } - int mx = 0; + set st(ps.begin(), ps.end()); + unordered_map mp; + int N = 0; + for (auto&& x : st) mp[x] = ++N; + // for (int i = 0; i <= n; ++i) { + // cerr << mp[ps[i]] << " \n"[i == n]; + // } + // for (auto&& [x, y] : mp) cerr << x << ' ' << y << '\n'; + segtree dp(N + 1); + dp.set(mp[0], {0}); + int prev = 0; for (int i = 1; i <= n; ++i) { - int sz = qu.query_size(i); - if (not (sz == 1 and a[i])) { - mx = max(mx, sz); - } - } - if (mx == n) { - cout << "YES\n"; - } else { - cout << "NO\n"; + int curr = max(prev, dp.range_query(0, mp[ps[i]]).val + i); + // debug(curr); + dp.apply(mp[ps[i]], { curr - i });; + prev = curr; } + // for (auto&& x : dp.serialize()) cerr << x.val << ' '; + // cerr << endl; + cout << prev << '\n'; } int main() { diff --git a/src/bin/std.in b/src/bin/std.in index 6e9dc99..653929e 100644 --- a/src/bin/std.in +++ b/src/bin/std.in @@ -1,35 +1,3 @@ -5 -4 3 -2 1 0 3 -1 2 -2 3 -3 4 -6 6 -0 1 2 3 0 1 -1 2 -2 3 -3 4 -4 5 -4 6 -5 6 -4 3 -0 1 2 0 -1 2 -2 3 -1 3 -4 6 -1 1 1 0 -1 2 -3 2 -4 3 -2 4 -4 1 -1 3 -5 5 -0 1 3 2 0 -1 2 -2 3 -3 4 -4 5 -3 5 +4 +-1 -2 -3 -4 diff --git a/src/bin/template.cc b/src/bin/template.cc index 513dfbc..4382877 100644 --- a/src/bin/template.cc +++ b/src/bin/template.cc @@ -120,6 +120,23 @@ struct pair_hash { } }; +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 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];)