regular backup

This commit is contained in:
arielherself 2024-12-26 02:52:49 +08:00
parent 6d72354324
commit 25a7d35f36
Signed by: arielherself
SSH Key Fingerprint: SHA256:AK3cyo9tFsp7Mox7K0sYphleC8hReXhnRKxwuDT5LBc
28 changed files with 12260 additions and 29 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "src/bin/cp-templates"]
path = src/bin/cp-templates
url = https://git.subc.rip/subcrip/cp-templates

598
src/bin/abc-385f.cc Normal file
View File

@ -0,0 +1,598 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
// #pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
using ld = __float128;
read(int, n);
readvec(pii, a, n);
auto check = [&] (ld b) -> bool {
ld prev = -INFLL;
for (auto&& [x, h] : a) {
ld curr = (h - b) / x;
if (curr > prev) {
prev = curr;
} else {
return false;
}
}
return true;
};
if (check(0)) {
cout << -1 << '\n';
return;
}
ld l = 0, r = 2e18;
while (r - l > 1e-10) {
ld mid = l + (r - l) / 2;
if (check(mid)) {
r = mid;
} else {
l = mid;
}
}
cout << fixed << setprecision(50) << (long double)(l) << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

29
src/bin/abc-385f.py Normal file
View File

@ -0,0 +1,29 @@
from decimal import Decimal
from sys import stdin
input = stdin.readline
n = int(input())
a = [list(map(int, input().split(' '))) for _ in range(n)]
def check(b):
prev: Decimal = Decimal(-10 ** 18)
for x, h in a:
curr: Decimal = (h - b) / x
if curr > prev:
prev = curr
else:
return False
return True
if check(0):
print(-1)
exit(0)
l = Decimal(0)
r = Decimal(10 ** 18)
cnt = 0
while r - l > 1e-10:
cnt += 1
mid = l + (r - l) / 2
if check(mid):
r = mid
else:
l = mid
print(l)
print(cnt)

751
src/bin/cf-2044g2.cc Normal file
View File

@ -0,0 +1,751 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
// #define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
namespace tarjan {
struct mutex_cond {
int v1; bool cond1;
int v2; bool cond2;
mutex_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {}
};
struct inclusive_cond {
int v1; bool cond1;
int v2; bool cond2;
inclusive_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {}
};
// Returns the mapping between vertices and their affiliated sccs.
vector<int> scc(const vector<vector<int>>& ch) {
int n = ch.size();
int cnt = 0, scn = 0;
vector<int> dfn(n), low(n), vis(n), st;
vector<int> br(n);
auto tarjan = [&] (auto tarjan, int v) -> void {
dfn[v]=low[v]=++cnt;
st.push_back(v);
vis[v]=1;
for(const auto&u:ch[v])
if(!dfn[u]) tarjan(tarjan, u),low[v]=min(low[v],low[u]);
else if(vis[u])low[v]=min(low[v],dfn[u]);
if(dfn[v]==low[v]){
++scn;
int u;
do u=st.back(), st.pop_back(),vis[u]=0,br[u]=scn; while(u!=v);
}
};
for (int i = 0; i < n; ++i) {
if (!dfn[i]) {
tarjan(tarjan, i);
}
}
return br;
}
// This method can eliminate redundant edges or self-loops
vector<vector<int>> build_scc(const vector<vector<int>>& ch) {
int n = ch.size();
auto br = scc(ch);
int cnt = *max_element(br.begin(), br.end());
vector<unordered_set<int, safe_hash>> rb(cnt + 1);
for (int i = 0; i < n; ++i) {
for (auto&& u : ch[i]) {
if (br[i] != br[u]) rb[br[i]].emplace(br[u]);
}
}
vector<vector<int>> res(cnt + 1);
for (int i = 1; i <= cnt; ++i) {
res[i] = vector<int>(rb[i].begin(), rb[i].end());
}
return res;
}
// This method can eliminate redundant edges or self-loops
// return form: (scc size, children of scc)
vector<pair<size_t, vector<int>>> build_scc_with_size(const vector<vector<int>>& ch) {
int n = ch.size();
auto br = scc(ch);
int cnt = *max_element(br.begin(), br.end());
vector<unordered_set<int, safe_hash>> rb(cnt + 1);
for (int i = 0; i < n; ++i) {
for (auto&& u : ch[i]) {
if (br[i] != br[u]) rb[br[i]].emplace(br[u]);
}
}
vector<pair<size_t, vector<int>>> res(cnt + 1);
for (int i = 1; i <= cnt; ++i) {
res[i].second = vector<int>(rb[i].begin(), rb[i].end());
}
for (int i = 1; i <= n; ++i) {
res[br[i]].first += 1;
}
return res;
}
// indices start from 1, result has `n` items
optional<vector<bool>> solve_twosat(int n, const vector<mutex_cond>& conditions) {
vector<vector<int>> ch(2 * n + 1);
for (auto&& [v1, cond1, v2, cond2] : conditions) {
ch[(1 ^ cond1) * n + v1].emplace_back(cond2 * n + v2);
ch[(1 ^ cond2) * n + v2].emplace_back(cond1 * n + v1);
}
auto sccno = scc(ch);
for (int i = 1; i <= n; ++i) {
if (sccno[i] == sccno[i + n]) {
return nullopt;
}
}
vector<bool> res;
for (int i = 1; i <= n; ++i) {
if (sccno[i] < sccno[i + n]) {
res.emplace_back(false);
} else {
res.emplace_back(true);
}
}
return res;
};
// indices start from 1, result has `n` items
optional<vector<bool>> solve_twosat(int n, const vector<inclusive_cond>& conditions) {
vector<mutex_cond> trans_conds;
for (auto&& [v1, cond1, v2, cond2] : conditions) {
trans_conds.emplace_back(v1, cond1, v2, not cond2);
}
return solve_twosat(n, trans_conds);
}
// Returns if each vertex is a cut vertex
// All indices start from 1
vector<int> cut_v(const vector<vector<int>>& ch) {
int n = ch.size() - 1;
vector<bool> vis(n + 1);
vector<int> low(n + 1), dfn(n + 1), flag(n + 1);
int cnt = 0;
auto dfs = [&] (auto dfs, int v, int pa) -> void {
vis[v] = 1;
low[v] = dfn[v] = ++cnt;
int child = 0;
for (auto&& u : ch[v]) {
if (not vis[u]) {
++child;
dfs(dfs, u, v);
low[v] = min(low[v], low[u]);
if (pa != v and low[u] >= dfn[v] and not flag[v]) {
flag[v] = 1;
}
} else if (u != pa) {
low[v] = min(low[v], dfn[u]);
}
}
if (pa == v and child >= 2 and not flag[v]) {
flag[v] = 1;
}
};
for (int i = 1; i <= n; ++i) {
if (not dfn[i]) {
dfs(dfs, i, 0);
}
}
return flag;
}
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
readvec1(int, nxt, n);
vector<int> scc;
{
adj(ch, n);
for (int i = 1; i <= n; ++i) {
Edge(ch, i, nxt[i]);
}
scc = tarjan::scc(ch);
}
int m = *max_element(scc.begin(), scc.end());
adj(ch, m);
vector<int> ind(m + 1);
for (int i = 1; i <= n; ++i) {
if (scc[i] == scc[nxt[i]]) {
continue;
}
Edge(ch, scc[i], scc[nxt[i]]);
ind[scc[nxt[i]]] += 1;
}
vector<int> dp(m + 1);
deque<int> q;
for (int i = 0; i <= m; ++i) {
if (ind[i] == 0) {
q.emplace_back(i);
}
}
while (q.size()) {
int v = popfront(q);
for (auto&& u : ch[v]) {
if (ch[u].empty()) {
chmax(dp[u], dp[v] + 1);
} else {
dp[u] += dp[v] + 1;
}
if (--ind[u] == 0) {
q.emplace_back(u);
}
}
}
cout << 2 + *max_element(dp.begin(), dp.end()) << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

591
src/bin/cf-2044h.cc Normal file
View File

@ -0,0 +1,591 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
// #define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n, q);
vector a(n, vector<int>(n));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> a[i][j];
}
}
vector f(n + 1, vector<ll>(n + 1));
vector g(n + 1, vector<ll>(n + 1));
vector h(n + 1, vector<ll>(n + 1));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + a[i - 1][j - 1];
g[i][j] = g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1] + a[i - 1][j - 1] * (i - 1);
h[i][j] = h[i - 1][j] + h[i][j - 1] - h[i - 1][j - 1] + a[i - 1][j - 1] * (j - 1);
}
}
while (q--) {
read(int, x1, y1, x2, y2);
--x1, --x2, --y1, --y2;
ll p = h[x2 + 1][y2 + 1] - h[x1][y2 + 1] - h[x2 + 1][y1] + h[x1][y1] - (y1 - 1) * (f[x2 + 1][y2 + 1] - f[x1][y2 + 1] - f[x2 + 1][y1] + f[x1][y1]);
ll q = (g[x2 + 1][y2 + 1] - g[x1][y2 + 1] - g[x2 + 1][y1] + g[x1][y1] - x1 * (f[x2 + 1][y2 + 1] - f[x1][y2 + 1] - f[x2 + 1][y1] + f[x1][y1])) * (y2 - y1 + 1);
cout << p + q << ' ';
}
cout << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

637
src/bin/cf-837f.cc Normal file
View File

@ -0,0 +1,637 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = __float128;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* constants */
constexpr int INF = 0x3f3f3f3f;
constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
constexpr ll MDL = 1e9 + 7;
constexpr ll PRIME = 998'244'353;
constexpr ll PRIMELL = 901017227882342239LL;
constexpr ll MDL1 = 8784491;
constexpr ll MDL2 = PRIME;
constexpr int128 INT128_MAX = numeric_limits<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : (a)) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), (a).begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : (a)) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, (long double)(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(const string& s, const string& t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> 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(const string& s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(int128(lhs.val) * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return lhs * mod(inverse(rhs.val, mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
using mll = MLL<PRIMELL>;
constexpr int N = 4e5 + 10;
mll fact[N];
void prep() {
fact[0] = fact[1] = 1;
for (int i = 2; i < N; ++i) {
fact[i] = fact[i - 1] * i;
}
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
read(ll, k);
vector<int128> a;
int f = 0;
for (int i = 0; i < n; ++i) {
read(int, x);
if (x == 0) {
if (f) {
a.emplace_back(x);
}
} else {
a.emplace_back(x);
f = 1;
}
}
n = a.size();
if (*max_element(a.begin(), a.end()) >= k) {
cout << 0 << '\n';
return;
}
if (n >= 4) {
int res = 0;
while (a[n - 1] < k) {
for (int i = 1; i < n; ++i) {
a[i] += a[i - 1];
}
res += 1;
}
cout << res << '\n';
} else {
auto work = [&] (ll x) {
x -= 1;
int128 res = 0;
// debug(x);
for (int i = 1; i <= n; ++i) {
int128 c = 1;
for (int j = 0; j < n - i; ++j) {
ll p = n - i + x - j, q = j + 1;
if (c * p > int128(1) * LLONG_MAX * q) {
return INT128_MAX;
}
c = c * p / q;
}
// deb(i, c);
res += c * a[i - 1];
}
// debug(res);
return res;
};
ll l = 1, r = INFLL;
while (l < r) {
ll mid = l + r >> 1;
if (work(mid) >= k) {
r = mid;
} else {
l = mid + 1;
}
}
cout << l << '\n';
}
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

624
src/bin/cf-840c.cc Normal file
View File

@ -0,0 +1,624 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
using mll = MLL<MDL>;
constexpr int N = 320;
mll fact[N], factrev[N + 1], s[N + 1];
void prep() {
fact[0] = factrev[0] = 1;
for (int i = 1; i < N; ++i) {
fact[i] = fact[i - 1] * i;
}
s[0] = 1;
for (int i = 1; i <= N; ++i) {
s[i] = s[i - 1] * fact[i - 1];
}
factrev[N] = 1 / s[N];
for (int i = N; i; --i) {
factrev[i - 1] = factrev[i] * fact[i - 1];
}
for (int i = 0; i < N; ++i) {
factrev[i] = factrev[i + 1] * s[i];
}
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
readvec(int, a, n);
unordered_map<int, int, safe_hash> cnt;
for (int i = 0; i < n; ++i) {
auto f = decompose_prime(a[i]);
int x = 1;
for (auto&& [v, c] : f) {
if (c % 2) {
x *= v;
}
}
cnt[x] += 1;
}
vector<int> b;
for (auto&& [v, c] : cnt) {
b.emplace_back(c);
}
vector<mll> dp(n);
dp[0] = 1;
int tot = 0;
for (auto&& x : b) {
vector<mll> ndp(n);
for (int j = 1; j <= x; ++j) {
mll choice = fastcomb((x - j) + j - 1, x - j) * fact[x];
int extra = x - j;
for (int k = 0; k < n; ++k) {
if (dp[k] == 0) continue;
for (int l = 0; l <= min(k, j); ++l) {
ndp[k - l + extra] += choice * dp[k] * fastcomb(k, l) * fastcomb(tot + 1 - k, j - l);
}
}
}
tot += x;
dp = std::move(ndp);
}
cout << dp[0] << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

623
src/bin/cf-840d.cc Normal file
View File

@ -0,0 +1,623 @@
// re-run
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
// #pragma GCC optimize("O2,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
constexpr int M = 60;
read(int, n, q);
readvec(int, a, n);
vector<tiii> queries;
vector<vector<int>> open(n + 1);
vector<vector<int>> close(n + 1);
vector<vector<int>> seq(q);
unordered_map<pii, int, pair_hash> oc;
for (int i = 0; i < q; ++i) {
read(int, l, r, x);
--l, --r;
queries.emplace_back(l, r, x);
// if (oc.count({l, r})) {
// seq[i] = seq[oc[{l, r}]];
// } else {
int nd = (r - l + 1) / x + 1;
for (int j = l; j <= r; j += nd) {
seq[i].emplace_back(a[j]);
}
// for (int j = 0; j < M; ++j) {
// int idx = rd() % (r - l + 1) + l;
// seq[i].emplace_back(a[idx]);
// }
// oc[{l, r}] = i;
// }
open[l].emplace_back(i);
close[r + 1].emplace_back(i);
}
vector<int> cnt(n + 1);
vector<int> res(q, INF);
// vector c(q, vector<int>(M));
vector<vector<int>> c(q);
for (int i = 0; i <= n; ++i) {
for (auto&& qi : open[i]) {
for (int j = 0; j < seq[qi].size(); ++j) {
// c[qi][j] = cnt[seq[qi][j]];
c[qi].emplace_back(cnt[seq[qi][j]]);
}
}
for (auto&& qi : close[i]) {
auto&& [l, r, k] = queries[qi];
for (int j = 0; j < seq[qi].size(); ++j) {
int val = seq[qi][j];
if (cnt[val] - c[qi][j] > (r - l + 1) / k) {
chmin(res[qi], val);
}
}
}
if (i < n) {
cnt[a[i]] += 1;
}
}
replace(res.begin(), res.end(), INF, -1);
putvec_eol(res);
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

684
src/bin/cf-855d.cc Normal file
View File

@ -0,0 +1,684 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T>
string bin(T x) {
if (x == 0) {
return "0";
}
string res;
while (x) {
res += (x & 1) + '0';
x >>= 1;
}
return string(res.rbegin(), res.rend());
}
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
struct LCA {
vector<int> depth;
vector<vector<int>> pa;
LCA(const vector<vector<int>>& g, const vector<int>& roots) {
int n = g.size() - 1;
int m = 32 - __builtin_clz(n);
depth.resize(n + 1);
pa.resize(n + 1, vector<int>(m, -1));
function<void(int, int)> dfs = [&](int x, int fa) {
pa[x][0] = fa;
for (int y: g[x]) {
if (y != fa) {
depth[y] = depth[x] + 1;
dfs(y, x);
}
}
};
for (auto&& v : roots) {
dfs(v, 0);
}
for (int i = 0; i < m - 1; i++)
for (int x = 1; x <= n; x++)
if (int p = pa[x][i]; p != -1)
pa[x][i + 1] = pa[p][i];
}
int get_kth_ancestor(int node, int k) {
for (; k; k &= k - 1)
node = pa[node][__builtin_ctz(k)];
return node;
}
int query(int x, int y) {
if (depth[x] > depth[y])
swap(x, y);
y = get_kth_ancestor(y, depth[y] - depth[x]);
if (y == x)
return x;
for (int i = pa[x].size() - 1; i >= 0; i--) {
int px = pa[x][i], py = pa[y][i];
if (px != py) {
x = px;
y = py;
}
}
return pa[x][0];
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
vector<int> fa(n + 1);
adj(ch, n);
vector<ll> ps(n + 1);
for (int i = 1; i <= n; ++i) {
read(int, p, t);
if (p == -1) continue;
fa[i] = p;
edge(ch, i, p);
ps[i] = t == 0 ? (1LL << 32) : 1;
}
vector<int> r(n + 1);
vector<int> roots;
{
int root;
auto dfs = [&] (auto dfs, int v, int pa) -> void {
r[v] = root;
ps[v] += ps[pa];
for (auto&& u : ch[v]) {
if (u == pa) continue;
dfs(dfs, u, v);
}
};
for (int i = 1; i <= n; ++i) {
if (not fa[i]) {
roots.emplace_back(i);
root = i;
dfs(dfs, i, 0);
}
}
}
read(int, q);
LCA lca(ch, roots);
while (q--) {
read(int, t, u, v);
if (t == 1) {
if (u != v and r[u] == r[v] and lca.query(u, v) == u and ((ps[v] - ps[u]) & ((1LL << 32) - 1)) == 0) {
cout << "YES\n";
} else {
cout << "NO\n";
}
} else {
if (u != v and r[u] == r[v]) {
int l = lca.query(u, v);
if (l != v and ((ps[u] - ps[l]) & (1LL << 32) - 1) == 0 and (ps[v] - ps[l] >> 32) == 0) {
cout << "YES\n";
continue;
}
}
cout << "NO\n";
}
}
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

660
src/bin/cf-858f.cc Normal file
View File

@ -0,0 +1,660 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = __float128;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : (a)) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), (a).begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : (a)) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, (long double)(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(const string& s, const string& t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> 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(const string& s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
class quick_union {
private:
vector<size_t> c, sz;
public:
quick_union(size_t n) : c(n), sz(n) {
iota(c.begin(), c.end(), 0);
sz.assign(n, 1);
}
size_t query(size_t i) {
if (c[i] != i) c[i] = query(c[i]);
return c[i];
}
void merge(size_t i, size_t j) {
if (connected(i, j)) return;
sz[query(j)] += sz[query(i)];
c[query(i)] = query(j);
}
bool connected(size_t i, size_t j) {
return query(i) == query(j);
}
size_t query_size(size_t i) {
return sz[query(i)];
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n, m);
vector<pii> edges;
quick_union qu(n + 1);
adj(ch, n);
for (int i = 0; i < m; ++i) {
read(int, u, v);
if (qu.connected(u, v)) {
edges.emplace_back(u, v);
} else {
qu.merge(u, v);
edge(ch, u, v);
}
}
vector<int> depth(n + 1, -1);
vector<int> fa(n + 1);
set<tiii> cand;
vector<int> cnt(n + 1);
{
auto dfs = [&] (auto dfs, int v, int pa) -> void {
fa[v] = pa;
depth[v] = depth[pa] + 1;
if (pa != 0) {
cand.emplace(depth[v], pa, v);
}
for (auto&& u : ch[v]) {
if (u == pa) continue;
cnt[qu.query(v)] += 1;
dfs(dfs, u, v);
}
};
for (int i = 1; i <= n; ++i) {
if (depth[i] == -1) {
dfs(dfs, i, 0);
}
}
}
for (auto&& [u, v] : edges) {
if (depth[u] > depth[v]) swap(u, v);
cnt[qu.query(v)] += 1;
cand.emplace(depth[u] + 1, u, v);
}
vector<tiii> res;
while (cand.size()) {
auto [d, u, v] = *cand.rbegin();
cand.erase(prev(cand.end()));
cnt[qu.query(v)] -= 1;
if (cnt[qu.query(v)] > 0) {
if (get<1>(*cand.rbegin()) == u) {
// remove two leaves w-u-v
auto [d_, u_, w] = *cand.rbegin();
cand.erase(prev(cand.end()));
res.emplace_back(w, u, v);
} else {
// remove one path fa[u]-u-v
assert(cand.count({depth[fa[u]] + 1, fa[u], u}));
cand.erase({depth[fa[u]] + 1, fa[u], u});
res.emplace_back(fa[u], u, v);
}
cnt[qu.query(v)] -= 1;
} else {
// only one edge in the current CC
}
}
cout << res.size() << '\n';
for (auto&& [u, v, w] : res) {
cout << u << ' ' << v << ' ' << w << '\n';
}
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

690
src/bin/cf-863f.cc Normal file
View File

@ -0,0 +1,690 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = __float128;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, (long double)(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
struct mcmf {
struct edge {
int to;
ll cap;
ll flow;
ll cost;
int rev;
int mark;
};
vector<vector<edge>> edges;
vector<ll> dis;
vector<bool> vis;
ll ret;
mcmf(int n) : edges(n + 1), dis(n + 1), vis(n + 1) {}
void add_edge(int from, int to, ll cap, ll cost, int mark = 0, int mark_rev = 0) {
edges[from].push_back({ to, cap, 0, cost, int(edges[to].size()), mark });
edges[to].push_back({ from, 0, 0, -cost, int(edges[from].size() - 1), mark_rev });
}
bool sp(int s, int t) {
dis.assign(edges.size(), INFLL);
dis[s] = 0;
int n = edges.size();
int f = 1;
while (f) {
f = 0;
for (int i = 0; i < n; ++i) {
for (auto&& [to, cap, flow, cost, rev, mark] : edges[i]) {
if (cap > flow and dis[to] > dis[i] + cost) {
dis[to] = dis[i] + cost;
f = 1;
}
}
}
}
return dis[t] != INFLL;
}
ll dfs(int s, int t, ll cap) {
if (vis[s]) {
return 0;
}
vis[s] = 1;
if (s == t) {
return cap;
}
ll res = 0;
int n = edges[s].size();
for (int i = 0; i < n; ++i) {
auto e = edges[s][i];
if (e.cap > e.flow and dis[e.to] == dis[s] + e.cost) {
ll nw = dfs(e.to, t, min(cap - res, e.cap - e.flow));
edges[s][i].flow += nw;
edges[e.to][e.rev].flow -= nw;
res += nw;
ret += nw * e.cost;
if (res == cap) {
return res;
}
}
}
return res;
}
// returns: (flow, cost)
pll run(int s, int t) {
ll res = 0; ret = 0;
while (sp(s, t)) {
vis.assign(edges.size(), 0);
ll curr = dfs(s, t, LLONG_MAX);
res += curr;
// BUG: this is a temporary fix of the infinite-looping issue observed
// when dealing with networks with negative weights.
if (curr == 0) break;
}
return { res, ret };
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n, q);
vector<int> mx(n, n - 1), mn(n, 0);
while (q--) {
read(int, t, l, r, x);
--l, --r, --x;
if (t == 1) {
for (int j = l; j <= r; ++j) {
chmax(mn[j], x);
}
} else {
for (int j = l; j <= r; ++j) {
chmin(mx[j], x);
}
}
}
vector<vector<int>> choice(n);
for (int i = 0; i < n; ++i) {
for (int j = mn[i]; j <= mx[i]; ++j) {
choice[j].emplace_back(i);
}
}
mcmf net(3 * n + 10);
int oc = 1, val = n + 1, pos = 2 * n + 1;
int s = 3 * n + 8, t = 3 * n + 9;
for (int i = 0; i < n; ++i) {
net.add_edge(s, oc + i, INF, 0);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
net.add_edge(oc + i, val + j, 1, 2 * i + 1);
}
}
for (int i = 0; i < n; ++i) {
for (auto&& j : choice[i]) {
net.add_edge(val + i, pos + j, 1, 0);
}
}
for (int i = 0; i < n; ++i) {
net.add_edge(pos + i, t, 1, 0);
}
auto [flow, cost] = net.run(s, t);
if (flow != n) {
cout << -1 << '\n';
} else {
cout << cost << '\n';
}
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

587
src/bin/cf-865c.cc Normal file
View File

@ -0,0 +1,587 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n, r);
readvec((array<int, 3>), a, n);
vector<ld> dp(r + 1);
for (int i = 1; i <= n; ++i) {
auto&& [f, s, rawp] = a[i - 1];
ld p = rawp / 100.;
vector<ld> ndp(r + 1, INFLL);
for (int j = 0; j <= r; ++j) {
if (j - f >= 0) {
chmin(ndp[j], dp[j - f] / p + f + (1 - p) / p * s);
}
if (j - s >= 0) {
chmin(ndp[j], dp[j - s] + p * f + (1 - p) * s);
}
}
dp = std::move(ndp);
debug(dp);
}
cout << fixed << setprecision(50) << dp[r] << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

0
src/bin/cf-868f.cc Normal file
View File

617
src/bin/cf-869e.cc Normal file
View File

@ -0,0 +1,617 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
template<typename T>
struct BIT2d {
int n, m;
vector<vector<T>> c;
BIT2d(size_t n, size_t m) : n(n), m(m), c(n + 1, vector<T>(m + 1)) {}
void add(size_t i, size_t j, const T& k) {
while (i <= n) {
size_t j1 = j;
while (j1 <= m) {
c[i][j1] xor_eq k;
j1 += lowbit(j1);
}
i += lowbit(i);
}
}
T getsum(size_t i, size_t j) {
T res = {};
while (i) {
size_t j1 = j;
while (j1) {
res xor_eq c[i][j1];
j1 -= lowbit(j1);
}
i -= lowbit(i);
}
return res;
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n, m, q);
BIT2d<size_t> tr(n + 1, m + 1);
array_hash hasher;
while (q--) {
read(int, op, x1, y1, x2, y2);
if (op != 3) {
auto h = hasher(initializer_list<int>{x1, y1, x2, y2});
tr.add(x1, y1, h);
tr.add(x1, y2 + 1, h);
tr.add(x2 + 1, y1, h);
tr.add(x2 + 1, y2 + 1, h);
} else {
if (tr.getsum(x1, y1) == tr.getsum(x2, y2)) {
cout << "Yes\n";
} else {
cout << "No\n";
}
}
}
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

644
src/bin/cf-873e.cc Normal file
View File

@ -0,0 +1,644 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
template<typename _Tp, typename _Op = function<_Tp(const _Tp&, const _Tp&)>> struct sparse_table {
_Op op;
vector<vector<_Tp>> st;
sparse_table() {}
template <typename ReverseIterator>
sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) {
op = __operation;
int n = distance(__first, __last);
st = vector<vector<_Tp>>(n, vector<_Tp>(int(log2(n) + 1)));
int i = n - 1;
for (auto it = __first; it != __last; ++it) {
st[i][0] = *it;
for (int j = 1; i + (1 << j) <= n; ++j) {
st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
i -= 1;
}
}
_Tp query(size_t __start, size_t __end) {
int s = lg2(__end - __start + 1);
return op(st[__start][s], st[__end - (1 << s) + 1][s]);
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
readvec(int, a, n);
vector<int> idx(n);
iota(idx.begin(), idx.end(), 0);
sort_by_key(idx.begin(), idx.end(), expr(a[i], auto&& i), greater());
vector<pii> diff(n);
for (int i = 0; i < n - 1; ++i) {
diff[i] = { a[idx[i]] - a[idx[i + 1]], i };
}
diff[n - 1] = { a[idx[n - 1]], n - 1 };
sparse_table<pii> rmq(diff.rbegin(), diff.rend(), functor(max));
tiii varmax = { -1, -1, -1 };
tiii mx = { -INF, -INF, -INF };
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
// 0..j | j+1..i | i+1..n-1
int l = j + 1, r = i - j;
if (l > r) swap(l, r);
if (r > 2 * l) continue;
int minlen = (r + 1) / 2, maxlen = 2 * l;
if (minlen > maxlen) continue;
int left = max(i + minlen, i + 1);
int right = min(i + maxlen, n - 1);
if (left > right) continue;
int x = a[idx[j]] - a[idx[j + 1]];
int y = a[idx[i]] - a[idx[i + 1]];
auto [z, zpos] = rmq.query(left, right);
// deb(i, j);
// deb(minlen, maxlen);
// deb(left, right);
// deb(x, y, z);
// deb(j, i, zpos);
tiii pos = { j, i, zpos };
tiii curr = { x, y, z };
if (chmax(mx, curr)) {
varmax = pos;
}
}
}
vector<int> res(n);
auto&& [xpos, ypos, zpos] = varmax;
for (int i = 0; i <= xpos; ++i) {
res[idx[i]] = 1;
}
for (int i = xpos + 1; i <= ypos; ++i) {
res[idx[i]] = 2;
}
for (int i = ypos + 1; i <= zpos; ++i) {
res[idx[i]] = 3;
}
for (int i = zpos + 1; i < n; ++i) {
res[idx[i]] = -1;
}
putvec(res);
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

656
src/bin/cf-873f.cc Normal file
View File

@ -0,0 +1,656 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
template <size_t N>
struct SAM {
vector<int> fa, len;
vector<bool> cloned;
vector<int> cnt;
vector<array<int, N>> ch;
vector<bool> valid;
int last;
int tot;
int create(int _fa, int _len, bool _cloned, array<int, N>&& _ch, bool _valid) {
fa.emplace_back(_fa);
len.emplace_back(_len);
cloned.emplace_back(_cloned);
ch.emplace_back(_ch);
valid.emplace_back(_valid);
return tot++;
}
SAM(void) : fa(2), len(2), cloned(2), ch(2), valid(2), last(1), tot(2) {}
void push_back(size_t c, bool valid) {
int p = last;
int nw = create(0, len[p] + 1, false, {}, valid);
while (p != 0 and ch[p][c] == 0) {
ch[p][c] = nw;
p = fa[p];
}
if (p == 0) {
fa[nw] = 1;
} else {
int q = ch[p][c];
if (len[q] == len[p] + 1) {
fa[nw] = q;
} else {
int nq = create(fa[q], len[p] + 1, true, array(ch[q]), false);
fa[nw] = fa[q] = nq;
while (p != 0 and ch[p][c] == q) {
ch[p][c] = nq;
p = fa[p];
}
}
}
last = nw;
}
template <typename T>
optional<int> find(const basic_string<T>& seq) {
int p = 1;
for (auto&& c : seq) {
if (ch[p][c] == 0) {
return nullopt;
}
p = ch[p][c];
}
return p;
}
// Fill `cnt` with the number of occurrences of each substring.
void populate(void) {
cnt.assign(tot, 0);
vector<int> idx(tot);
iota(idx.begin(), idx.end(), 0);
sort_by_key(idx.begin(), idx.end(), expr(len[i], auto&& i), greater());
for (auto&& v : idx) {
if (v > 1 and not cloned[v] and valid[v]) {
cnt[v] += 1;
}
cnt[fa[v]] += cnt[v];
}
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
read(string, s);
read(string, v);
SAM<26> sam;
for (int i = 0; i < n; ++i) {
sam.push_back(s[i] - 'a', v[i] == '0');
}
sam.populate();
ll res = 0;
for (int i = 0; i < sam.tot; ++i) {
// deb(sam.cnt[i], sam.len[i]);
chmax(res, ll(1) * sam.cnt[i] * sam.len[i]);
}
cout << res << endl;
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

600
src/bin/cf-875e.cc Normal file
View File

@ -0,0 +1,600 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n, s1, s2);
readvec1(int, pos, n);
pos[0] = s2;
auto check = [&] (int dis) -> bool {
set<int> cand;
if (abs(s1 - s2) <= dis) {
cand.emplace(s1);
}
for (int i = 1; i <= n; ++i) {
// use the alternating pointer
if (cand.size() and abs(pos[i - 1] - pos[i]) <= dis) {
cand.emplace(pos[i - 1]);
}
// use the last pointer
// don't need to do anything
while (cand.size() and abs(*cand.begin() - pos[i]) > dis) {
cand.erase(cand.begin());
}
while (cand.size() and abs(*cand.rbegin() - pos[i]) > dis) {
cand.erase(prev(cand.end()));
}
}
return cand.size();
};
int l = 0, r = INF;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
cout << l << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

673
src/bin/cf-877f.cc Normal file
View File

@ -0,0 +1,673 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
template <typename record_t>
vector<typename record_t::return_t> mo(record_t& solver, const vector<pii>& queries, int n) {
int m = queries.size();
int block = sqrt(ld(n));
vector<int> idx(m);
iota(idx.begin(), idx.end(), 0);
// sort_by_key(idx.begin(), idx.end(), expr(queries[i], int i));
sort(idx.begin(), idx.end(), [&] (int i, int j) {
auto&& lhs = queries[i];
auto&& rhs = queries[j];
if (lhs.first / block != rhs.first / block) {
return lhs.first < rhs.first;
}
if (lhs.first / block % 2) {
return lhs.second < rhs.second;
}
return lhs.second > rhs.second;
}); // TODO: optimized sorting
vector<typename record_t::return_t> res(m);
for (auto&& i : idx) {
auto&& [tl, tr] = queries[i];
while (solver.l > tl) solver.movell();
while (solver.r < tr) solver.moverr();
while (solver.l < tl) solver.movelr();
while (solver.r > tr) solver.moverl();
res[i] = solver.get();
}
return res;
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n, k);
readvec(int, t, n);
readvec(int, c, n);
struct {
using return_t = ll;
int l = 0, r = 0; // maintaining answer of range [l, r]
return_t res = 0;
vector<int> me;
vector<int> lt;
vector<int> gt;
vector<int> cnt;
int k;
return_t get(void) const {
return res;
}
void movell(void) {
l -= 1;
if (gt[l] != -1) {
res += cnt[gt[l]];
}
cnt[me[l]] += 1;
}
void movelr(void) {
cnt[me[l]] -= 1;
if (gt[l] != -1) {
res -= cnt[gt[l]];
}
l += 1;
}
void moverl(void) {
cnt[me[r]] -= 1;
if (lt[r] != -1) {
res -= cnt[lt[r]];
}
r -= 1;
}
void moverr(void) {
r += 1;
if (lt[r] != -1) {
res += cnt[lt[r]];
}
cnt[me[r]] += 1;
}
} solver;
vector<ll> ps(n + 1);
vector<ll> oc(n + 1);
for (int i = 1; i <= n; ++i) {
ps[i] = ps[i - 1] + (t[i - 1] == 1 ? 1 : -1) * c[i - 1];
oc[i] = ps[i];
}
sort(oc.begin(), oc.end());
int m = unique(oc.begin(), oc.end()) - oc.begin();
oc.resize(m);
solver.me.assign(n + 1, 0);
solver.lt.assign(n + 1, -1);
solver.gt.assign(n + 1, -1);
solver.cnt.assign(m, 0);
for (int i = 0; i <= n; ++i) {
solver.me[i] = lower_bound(oc.begin(), oc.end(), ps[i]) - oc.begin();
{
auto it = lower_bound(oc.begin(), oc.end(), ps[i] - k);
if (it == oc.end() or *it != ps[i] - k);
else solver.lt[i] = it - oc.begin();
}
{
auto it = lower_bound(oc.begin(), oc.end(), ps[i] + k);
if (it == oc.end() or *it != ps[i] + k);
else solver.gt[i] = it - oc.begin();
}
}
solver.k = k;
solver.cnt[lower_bound(oc.begin(), oc.end(), 0) - oc.begin()] = 1;
read(int, q);
readvec(pii, queries, q);
transform(queries.begin(), queries.end(), queries.begin(), expr(pii(p.first - 1, p.second), auto&& p));
vector res = mo(solver, queries, n);
putvec_eol(res);
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

0
src/bin/cf-878b.cc Normal file
View File

613
src/bin/cf-884e.cc Normal file
View File

@ -0,0 +1,613 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n, m);
auto get = [&] (char c) {
if (c >= '0' and c <= '9') {
return c - '0';
} else {
return 10 + c - 'A';
}
};
constexpr int N = 1 << 26;
bitset<N> a;
for (int i = 0; i < n; ++i) {
read(string, s);
for (int j = 0; j < m / 4; ++j) {
int mask = get(s[j]);
for (int k = 0; k < 4; ++k) {
int bit = mask >> (3 - k) bitand 1;
a[i * m + j * 4 + k] = bit;
}
}
}
auto check = [&] (int i, int j) { return i >= 0 and i < n and j >= 0 and j < m; };
auto dfs = [&] (auto dfs, int x, int y) -> void {
a[x * m + y] = 0;
for (auto&& [x1, y1] : initializer_list<pii> {{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}}) {
if (check(x1, y1) and a[x1 * m + y1]) {
dfs(dfs, x1, y1);
}
}
};
int res = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (a[i * m + j]) {
deque<pii> q = {{ i, j }};
while (q.size()) {
auto [x, y] = popfront(q);
for (auto&& [x1, y1] : initializer_list<pii> {{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}}) {
if (check(x1, y1) and a[x1 * m + y1]) {
q.emplace_back(x1, y1);
}
}
}
res += 1;
}
}
}
cout << res << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

675
src/bin/cf-884f.cc Normal file
View File

@ -0,0 +1,675 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
struct mcmf {
struct edge {
int to;
ll cap;
ll flow;
ll cost;
int rev;
int mark;
};
vector<vector<edge>> edges;
vector<ll> dis;
vector<bool> vis;
ll ret;
mcmf(int n) : edges(n + 1), dis(n + 1), vis(n + 1) {}
void add_edge(int from, int to, ll cap, ll cost, int mark = 0, int mark_rev = 0) {
edges[from].push_back({ to, cap, 0, cost, int(edges[to].size()), mark });
edges[to].push_back({ from, 0, 0, -cost, int(edges[from].size() - 1), mark_rev });
}
bool sp(int s, int t) {
dis.assign(edges.size(), INFLL);
dis[s] = 0;
int n = edges.size();
int f = 1;
while (f) {
f = 0;
for (int i = 0; i < n; ++i) {
for (auto&& [to, cap, flow, cost, rev, mark] : edges[i]) {
if (cap > flow and dis[to] > dis[i] + cost) {
dis[to] = dis[i] + cost;
f = 1;
}
}
}
}
return dis[t] != INFLL;
}
ll dfs(int s, int t, ll cap) {
if (vis[s]) {
return 0;
}
vis[s] = 1;
if (s == t) {
return cap;
}
ll res = 0;
int n = edges[s].size();
for (int i = 0; i < n; ++i) {
auto e = edges[s][i];
if (e.cap > e.flow and dis[e.to] == dis[s] + e.cost) {
ll nw = dfs(e.to, t, min(cap - res, e.cap - e.flow));
edges[s][i].flow += nw;
edges[e.to][e.rev].flow -= nw;
res += nw;
ret += nw * e.cost;
if (res == cap) {
return res;
}
}
}
return res;
}
// returns: (flow, cost)
pll run(int s, int t) {
ll res = 0; ret = 0;
while (sp(s, t)) {
vis.assign(edges.size(), 0);
ll curr = dfs(s, t, LLONG_MAX);
res += curr;
// BUG: this is a temporary fix of the infinite-looping issue observed
// when dealing with networks with negative weights.
if (curr == 0) break;
}
return { res, ret };
}
};
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
vector<int> a(n);
for (int i = 0; i < n; ++i) {
read(char, c);
a[i] = c - 'a';
}
readvec(int, b, n);
mcmf net(4 * n * 26 + 3);
int filter1 = 1, filter2 = n / 2 * 26 + 1, split = n * 26 + 1, node = 2 * n * 26 + 1, base = 2 * n * 26 + n + 1;
int s = 4 * n * 26 - 1, t = 4 * n * 26 - 2;
for (int i = 0; i < n; ++i) {
net.add_edge(s, base + i, 1, 0);
for (int j = 0; j < n; ++j) {
net.add_edge(base + i, filter1 + (j >= n / 2 ? n - 1 - j : j) * 26 + a[i], 1, 0);
}
}
for (int i = 0; i < n / 2; ++i) {
for (int j = 0; j < 26; ++j) {
net.add_edge(filter1 + i * 26 + j, filter2 + i * 26 + j, 1, 0);
net.add_edge(filter2 + i * 26 + j, split + i * 26 + j, 1, a[i] == j ? -b[i] : 0);
net.add_edge(filter2 + i * 26 + j, split + (n - 1 - i) * 26 + j, 1, a[n - 1 - i] == j ? -b[n - 1 - i] : 0);
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 26; ++j) {
net.add_edge(split + i * 26 + j, node + i, 1, 0);
}
net.add_edge(node + i, t, 1, 0);
}
auto [flow, cost] = net.run(s, t);
debug(flow);
cout << -cost << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

609
src/bin/cf-888f.cc Normal file
View File

@ -0,0 +1,609 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
// #pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
// __attribute__((target("popcnt")))
void solve() {
read(int, n);
vector a(n, vector<int>(n));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> a[i][j];
}
}
vector cache(n, vector(n, vector<ll>(2, -1)));
auto dfs = [&] (auto dfs, int l, int r, int left) -> ll {
if (l == r) return (left and a[l][l - 1]) + a[r][(r + 1) % n];
else if (l > r) return 1;
if (cache[l][r][left] != -1) {
return cache[l][r][left];
}
ll res = 0;
if (left) {
int u = (l - 1) % n;
for (int i = l; i <= r; ++i) {
if (a[u][i]) {
res = (res + dfs(dfs, l, i - 1, true) * dfs(dfs, i + 1, r, true) % MDL) % MDL;
// deb(l, r, u, i, res);
}
}
}
// connect to the right bound
{
int u = (r + 1) % n;
for (int i = l; i <= r; ++i) {
if (a[u][i]) {
res = (res + dfs(dfs, l, i - 1, false) * dfs(dfs, i + 1, r, true) % MDL) % MDL;
// deb(l, r, i, u, res);
}
}
}
return cache[l][r][left] = res;
};
ll res = 0;
for (int i = 1; i < n; ++i) {
if (a[0][i]) {
res = (res + dfs(dfs, 1, i - 1, false) * dfs(dfs, i + 1, n - 1, true) % MDL) % MDL;
}
}
cout << res << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

1
src/bin/cp-templates Submodule

@ -0,0 +1 @@
Subproject commit df3c66d5bffce87c763911d8e78987da8ef135de

653
src/bin/lg-3804.cc Normal file
View File

@ -0,0 +1,653 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
// #pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
#include<bits/stdc++.h>
using namespace std;
/* macro helpers */
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define __DECOMPOSE_S(a, x) auto x = a;
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
constexpr void __() {}
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
#define __as_typeof(container) remove_reference<decltype(container)>::type
template <typename T> struct argument_type;
template <typename T, typename U> struct argument_type<T(U)> { using type = U; };
/* type aliases */
#if LONG_LONG_MAX != INT64_MAX
using ll = int64_t;
using ull = uint64_t;
#else
using ll = long long;
using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>; using tiil = tuple<int, int, ll>; using tiid = tuple<int, int, ld>;
using tili = tuple<int, ll, int>; using till = tuple<int, ll, ll>; using tild = tuple<int, ll, ld>;
using tidi = tuple<int, ld, int>; using tidl = tuple<int, ld, ll>; using tidd = tuple<int, ld, ld>;
using tlii = tuple<ll, int, int>; using tlil = tuple<ll, int, ll>; using tlid = tuple<ll, int, ld>;
using tlli = tuple<ll, ll, int>; using tlll = tuple<ll, ll, ll>; using tlld = tuple<ll, ll, ld>;
using tldi = tuple<ll, ld, int>; using tldl = tuple<ll, ld, ll>; using tldd = tuple<ll, ld, ld>;
using tdii = tuple<ld, int, int>; using tdil = tuple<ld, int, ll>; using tdid = tuple<ld, int, ld>;
using tdli = tuple<ld, ll, int>; using tdll = tuple<ld, ll, ll>; using tdld = tuple<ld, ll, ld>;
using tddi = tuple<ld, ld, int>; using tddl = tuple<ld, ld, ll>; using tddd = tuple<ld, ld, ld>;
template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<>>;
template <typename T> using oi = ostream_iterator<T>;
template <typename T> using ii = istream_iterator<T>;
/* 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<int128>::max();
constexpr uint128 UINT128_MAX = numeric_limits<uint128>::max();
constexpr int128 INT128_MIN = numeric_limits<int128>::min();
constexpr uint128 UINT128_MIN = numeric_limits<uint128>::min();
/* random */
mt19937_64 rd(chrono::duration_cast<chrono::milliseconds>(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<upair>
#define ugt std::greater<upair>
#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 <typename T, typename U>
size_t operator()(const pair<T, U>& 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<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
template <typename Sequence>
size_t operator()(const Sequence& arr) const {
size_t pw1 = 1, pw2 = 1;
size_t res1 = 0, res2 = 0;
for (auto&& x : arr) {
res1 = (res1 + x * pw1) % __array_hash_mdl1;
res2 = (res2 + x * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
return res1 + res2;
}
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
#define edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__), ch[v].emplace_back(u, __VA_ARGS__);)
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
#define Edgew(ch, u, v, ...) __AS_PROCEDURE(ch[u].emplace_back(v, __VA_ARGS__);)
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
map<T, size_t> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
set<T> st(__first, __last);
size_t N = 0;
unordered_map<T, size_t, safe_hash> mp;
for (auto&& x : st) mp[x] = ++N;
return {N, mp};
}
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
template <typename T, size_t N> ostream& operator<<(ostream&, const array<T, N>&);
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>&, const std::tuple<Args...>&);
template<typename T> ostream& operator<<(ostream&, const vector<T>&);
std::ostream& operator<<(std::ostream&, const int128&);
template<typename T, typename U> istream& operator>>(istream& in, pair<T, U>& p) {
return in >> p.first >> p.second;
}
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
for (size_t i = 0; i < N; ++i) in >> a[i];
return in;
}
template <typename T, size_t N> ostream& operator<<(ostream& out, const array<T, N>& a) {
for (auto&& i : a) out << i << ' ';
return out;
}
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
using swallow = int[]; // guaranties left to right order
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
}
template<typename Char, typename Traits, typename... Args>
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
os << "{";
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
return os << "}";
}
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
for (auto&& i : vec) out << i << ' ';
return out;
}
std::ostream& operator<<(std::ostream& dest, const int128& value) {
// https://stackoverflow.com/a/25115163/23881100
std::ostream::sentry s( dest );
if ( s ) {
uint128 tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do {
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
template <typename Container>
inline auto poptop(Container& q) {
auto ret = q.top();
q.pop();
return ret;
}
template <typename Container>
inline auto popback(Container& q) {
auto ret = q.back();
q.pop_back();
return ret;
}
template <typename Container>
inline auto popfront(Container& q) {
auto ret = q.front();
q.pop_front();
return ret;
}
/* math */
template <typename return_t>
return_t qpow(ll b, ll p) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
return_t half = qpow<return_t>(b, p / 2);
if (p % 2 == 1) return half * half * b;
else return half * half;
}
// dynamic modulus
ll qpow(ll b, ll p, ll mod) {
if (b == 0 and p != 0) return 0;
if (p == 0) return 1;
ll half = qpow(b, p / 2, mod);
if (p % 2 == 1) return (int128(half) * half % mod) * b % mod;
else return half * half % mod;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
#pragma GCC diagnostic pop
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
__attribute__((target("lzcnt")))
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
template <typename T>
T mygcd(T a, T b) { return b == 0 ? a : mygcd(b, a % b); }
void __exgcd(ll a, ll b, ll& x, ll& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
__exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll inverse(ll a, ll b) {
ll x, y;
__exgcd(a, b, x, y);
return mod(x, b);
}
vector<tuple<int, int, ll>> decompose(ll x) {
// return (factor, count, factor ** count)
vector<tuple<int, int, ll>> res;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
int cnt = 0;
ll pw = 1;
while (x % i == 0) ++cnt, x /= i, pw *= i;
res.emplace_back(i, cnt, pw);
}
}
if (x != 1) {
res.emplace_back(x, 1, x);
}
return res;
}
vector<pii> decompose_prime(int N) {
// return (factor, count)
vector<pii> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
int cnt = 0;
while (N % i == 0) N /= i, ++cnt;
result.emplace_back(i, cnt);
}
}
if (N != 1) {
result.emplace_back(N, 1);
}
return result;
}
/* string algorithms */
vector<int> calc_next(string t) { // pi function of t
int n = (int)t.length();
vector<int> 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<int> calc_z(string t) { // z function of t
int m = t.length();
vector<int> z;
z.push_back(m);
pair<int, int> 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<int> kmp(string s, string t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
vector<int> lps = calc_next(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int n = s.length();
auto z = calc_z(s);
for (int i = 1; i <= n / 2; ++i) {
if (n % i == 0 && z[i] == n - i) {
return i;
}
}
return n;
}
/* modular arithmetic */
template <ll mdl> struct MLL {
ll val;
MLL(ll v = 0) : val(mod(v, mdl)) {}
MLL(const MLL<mdl>& other) : val(other.val) {}
friend MLL operator+(const MLL& lhs, const MLL& rhs) { return mod(lhs.val + rhs.val, mdl); }
friend MLL operator-(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - rhs.val, mdl); }
friend MLL operator*(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * rhs.val, mdl); }
friend MLL operator/(const MLL& lhs, const MLL& rhs) { return mod(lhs.val * mod(inverse(rhs.val, mdl), mdl), mdl); }
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, mdl); }
friend bool operator==(const MLL& lhs, const MLL& rhs) { return lhs.val == rhs.val; }
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
};
template <ll mdl>
ostream& operator<<(ostream& out, const MLL<mdl>& num) {
return out << num.val;
}
template <ll mdl>
istream& operator>>(istream& in, MLL<mdl>& num) {
return in >> num.val;
}
// miscancellous
template <typename T, typename U>
bool chmax(T& lhs, const U& rhs) {
bool ret = lhs < rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
template <typename T, typename U>
bool chmin(T& lhs, const U& rhs) {
bool ret = lhs > rhs;
if (ret) {
lhs = rhs;
}
return ret;
}
#define functor(func) ([&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);})
#define expr(ret, ...) ([&] (__VA_ARGS__) { return (ret); })
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
template <typename Func, typename RandomIt, typename Compare> void sort_by_key(RandomIt first, RandomIt last, Func extractor, Compare comp) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return comp(extractor(a), extractor(b)); });
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip(Iterator_T a_first, Iterator_T a_last, Iterator_U b_first, Iterator_U b_last) {
vector<pair<T, U>> res;
auto a_it = a_first;
auto b_it = b_first;
for (; not (a_it == a_last) and not (b_it == b_last); ++a_it, ++b_it) {
res.emplace_back(*a_it, *b_it);
}
return res;
}
template <typename T, typename U, typename Iterator_T, typename Iterator_U>
vector<pair<T, U>> zip_n(Iterator_T a_first, Iterator_U b_first, size_t n) {
vector<pair<T, U>> res;
if (n > 0) {
res.emplace_back(*a_first, *b_first);
for (size_t i = 1; i != n; ++i) {
res.emplace_back(*++a_first, *++b_first);
}
}
return res;
}
template <typename T>
class ArithmeticIterator : bidirectional_iterator_tag {
public:
using difference_type = ptrdiff_t;
using value_type = T;
private:
value_type value;
public:
ArithmeticIterator(const T& value) : value(value) {}
value_type operator*() const { return value; }
ArithmeticIterator<T>& operator++() { ++value; return *this; }
ArithmeticIterator<T>& operator--() { --value; return *this; }
bool operator==(const ArithmeticIterator<T>& rhs) const { return value == rhs.value; }
};
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define initarray(init, N) (__initarray<decay<decltype(init)>::type, (N)>(init))
namespace detail {
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), value)...}};
}
}
template <typename T, std::size_t N>
constexpr std::array<T, N> __initarray(const T& value) {
return detail::make_array(value, std::make_index_sequence<N>());
}
/*******************************************************/
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
void dump() {}
void dump_ignore() {}
void prep() {
}
template <size_t N>
struct SAM {
vector<int> fa, len;
vector<bool> cloned;
vector<int> cnt;
vector<array<int, N>> ch;
int last;
int tot;
int create(int _fa, int _len, bool _cloned, array<int, N>&& _ch) {
fa.emplace_back(_fa);
len.emplace_back(_len);
cloned.emplace_back(_cloned);
ch.emplace_back(_ch);
return tot++;
}
SAM(void) : fa(2), len(2), cloned(2), ch(2), last(1), tot(2) {}
void push_back(size_t c) {
int p = last;
int nw = create(0, len[p] + 1, false, {});
while (p != 0 and ch[p][c] == 0) {
ch[p][c] = nw;
p = fa[p];
}
if (p == 0) {
fa[nw] = 1;
} else {
int q = ch[p][c];
if (len[q] == len[p] + 1) {
fa[nw] = q;
} else {
int nq = create(fa[q], len[p] + 1, true, array(ch[q]));
fa[nw] = fa[q] = nq;
while (p != 0 and ch[p][c] == q) {
ch[p][c] = nq;
p = fa[p];
}
}
}
last = nw;
}
template <typename T>
optional<int> find(const basic_string<T>& seq) {
int p = 1;
for (auto&& c : seq) {
if (ch[p][c] == 0) {
return nullopt;
}
p = ch[p][c];
}
return p;
}
// Fill `cnt` with the number of occurrences of each substring.
void populate(void) {
cnt.assign(tot, 0);
vector<int> idx(tot);
iota(idx.begin(), idx.end(), 0);
sort_by_key(idx.begin(), idx.end(), expr(len[i], auto&& i), greater());
for (auto&& v : idx) {
if (v > 1 and not cloned[v]) {
cnt[v] += 1;
}
cnt[fa[v]] += cnt[v];
}
}
};
// __attribute__((target("popcnt")))
void solve() {
read(string, s);
SAM<26> sam;
for (auto&& c : s) {
sam.push_back(c - 'a');
}
sam.populate();
ll res = 0;
for (int i = 0; i < sam.tot; ++i) {
if (sam.cnt[i] != 1) {
chmax(res, ll(1) * sam.cnt[i] * sam.len[i]);
}
}
cout << res << '\n';
}
int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
static_assert(false, "incompatible compiler variant detected.");
#endif
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();
#else
read(int, t);
for (int i = 0; i < t; ++i) {
#ifdef DUMP_TEST_CASE
if (t != (TOT_TEST_CASE)) {
solve();
} else if (i + 1 == (DUMP_TEST_CASE)) {
dump();
} else {
dump_ignore();
}
#else
solve();
#endif
}
#endif
}

View File

@ -1,2 +1,3 @@
4
1 2 3 4
3 1000000000000000000
5 4 5

View File

@ -25,7 +25,7 @@ using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using ld = __float128;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
@ -48,6 +48,7 @@ constexpr int INF = 0x3f3f3f3f;
constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
constexpr ll MDL = 1e9 + 7;
constexpr ll PRIME = 998'244'353;
constexpr ll PRIMELL = 901017227882342239LL;
constexpr ll MDL1 = 8784491;
constexpr ll MDL2 = PRIME;
constexpr int128 INT128_MAX = numeric_limits<int128>::max();
@ -96,9 +97,9 @@ struct igt {
/* 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;)
#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 {
@ -132,13 +133,15 @@ struct pair_hash {
uniform_int_distribution<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
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;
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
@ -173,7 +176,7 @@ template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, s
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
@ -239,14 +242,14 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) {
template<typename T> void __read(T& x) { cin >> x; }
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), a.begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : (a)) cin >> x;)
#define readvec1(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a((n) + 1); copy_n(ii<argument_type<void(t)>::type>(cin), (n), (a).begin() + 1);)
#define putvec(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec1(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
#define putvec_eol(a) __AS_PROCEDURE(copy((a).begin(), (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define putvec1_eol(a) __AS_PROCEDURE(copy((a).begin() + 1, (a).end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : (a)) cerr << x << ' '; cerr << endl;)
#define deb(...) debug(make_tuple(__VA_ARGS__))
/* pops */
@ -293,7 +296,7 @@ ll qpow(ll b, ll p, ll mod) {
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
ll l = 0, r = pow(LLONG_MAX, (long double)(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
@ -393,7 +396,7 @@ vector<int> calc_z(string t) { // z function of t
}
return z;
}
vector<int> kmp(string s, string t) { // find all t in s
vector<int> kmp(const string& s, const string& t) { // find all t in s
string cur = t + '#' + s;
int sz1 = s.size(), sz2 = t.size();
vector<int> v;
@ -403,7 +406,7 @@ vector<int> kmp(string s, string t) { // find all t in s
}
return v;
}
int period(string s) { // find the length of shortest recurring period
int period(const 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) {

View File

@ -1,4 +1,5 @@
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
#include <ratio>
#pragma GCC optimize("Ofast,unroll-loops")
/************* This code requires C++17. ***************/
@ -25,7 +26,7 @@ using ull = unsigned long long;
#endif
using int128 = __int128_t;
using uint128 = __uint128_t;
using ld = long double;
using ld = __float128;
using pii = pair<int, int>; using pil = pair<int, ll>; using pid = pair<int, ld>;
using pli = pair<ll, int>; using pll = pair<ll, ll>; using pld = pair<ll, ld>;
using pdi = pair<ld, int>; using pdl = pair<ld, ll>; using pdd = pair<ld, ld>;
@ -132,13 +133,15 @@ struct pair_hash {
uniform_int_distribution<mt19937::result_type> dist(PRIME);
const size_t __array_hash_b = 31, __array_hash_mdl1 = dist(rd), __array_hash_mdl2 = dist(rd);
struct array_hash {
safe_hash hasher;
template <typename Sequence>
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;
auto h = hasher(x);
res1 = (res1 + h * pw1) % __array_hash_mdl1;
res2 = (res2 + h * pw2) % __array_hash_mdl2;
pw1 = (pw1 * __array_hash_b) % __array_hash_mdl1;
pw2 = (pw2 * __array_hash_b) % __array_hash_mdl2;
}
@ -173,7 +176,7 @@ template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, s
/* io */
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
// add declarations to avoid cyclic dependency
// add declarations to avoid circular dependency
template<typename T, typename U> istream& operator>>(istream&, pair<T, U>&);
template<typename T, typename U> ostream& operator<<(ostream&, const pair<T, U>&);
template<typename T, size_t N> istream& operator>>(istream&, array<T, N>&);
@ -293,7 +296,7 @@ ll qpow(ll b, ll p, ll mod) {
#pragma GCC diagnostic ignored "-Wparentheses"
// Accurately find `i` 'th root of `n` (taking the floor)
inline ll root(ll n, ll i) {
ll l = 0, r = pow(LLONG_MAX, ld(1) / i);
ll l = 0, r = pow(LLONG_MAX, (long double)(1) / i);
while (l < r) {
ll mid = l + r + 1 >> 1;
if (qpow<int128>(mid, i) <= n) {
@ -524,7 +527,7 @@ constexpr std::array<T, N> __initarray(const T& value) {
}
/*******************************************************/
// #define SINGLE_TEST_CASE
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
@ -537,6 +540,12 @@ void prep() {
// __attribute__((target("popcnt")))
void solve() {
for (int i = 9; ; i += 9) {
if (parity(i)) {
debug(i);
return;
}
}
}
int main() {

View File

@ -8,7 +8,7 @@ import io
PRIME = 998_244_353
if __name__ == '__main__':
N = 10 ** 6
print(N, N)
print(*(f'{randint(1, N)} {randint(1, N)} {randint(0, 10 ** 8)}' for _ in range(N)))
print(randint(1, N))
N = 2 * (10 ** 5)
print(N)
for i in range(N):
print(i + 1, randint(1, 10 ** 9))