backup
This commit is contained in:
parent
0b2e842d7f
commit
edd620dce2
|
@ -0,0 +1,527 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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 N = 10010;
|
||||||
|
read(int, n);
|
||||||
|
readvec(int, a, n);
|
||||||
|
unordered_map<int, int, safe_hash> cnt;
|
||||||
|
vector dp(N, vector(n + 1, pii(INF, -INF)));
|
||||||
|
dp[0][0] = { INF - 1, -INF };
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
cnt[a[i]] += 1;
|
||||||
|
vector ndp = dp;
|
||||||
|
for (int j = 0; j + a[i] < N; ++j) {
|
||||||
|
for (int k = 0; k < n; ++k) {
|
||||||
|
if (dp[j][k].first < INF) {
|
||||||
|
chmin(ndp[j + a[i]][k + 1].first, min(dp[j][k].first, a[i]));
|
||||||
|
chmax(ndp[j + a[i]][k + 1].second, max(dp[j][k].second, a[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dp = std::move(ndp);
|
||||||
|
}
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < N; ++i) {
|
||||||
|
for (int j = 0; j <= n; ++j) {
|
||||||
|
if (dp[i][j].first == dp[i][j].second) {
|
||||||
|
int curr = cnt.size() == 2 ? n : j;
|
||||||
|
chmax(res, curr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,545 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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);
|
||||||
|
readvec((array<ll, 4>), a, n);
|
||||||
|
ll res = 0;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
auto&& [x1, y1, x2, y2] = a[i];
|
||||||
|
res += gcd(abs(x2 - x1), abs(y2 - y1)) + 1;
|
||||||
|
unordered_set<pll, pair_hash> oc;
|
||||||
|
for (int j = 0; j < i; ++j) {
|
||||||
|
auto&& [x3, y3, x4, y4] = a[j];
|
||||||
|
ll px = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
|
||||||
|
ll py = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
|
||||||
|
ll q = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
||||||
|
if (q != 0 and px % q == 0 and py % q == 0 and px / q >= max(min(x1, x2), min(x3, x4)) and px / q <= min(max(x1, x2), max(x3, x4)) and py / q >= max(min(y1, y2), min(y3, y4)) and py / q <= min(max(y1, y2), max(y3, y4))) {
|
||||||
|
oc.emplace(px / q, py / q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res -= oc.size();
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,547 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
constexpr int m = 64;
|
||||||
|
read(ll, n);
|
||||||
|
vector<ll> f(m);
|
||||||
|
ll res = 0;
|
||||||
|
for (int i = m - 1; i > 1; --i) {
|
||||||
|
f[i] = root(n, i) - 1;
|
||||||
|
for (int j = 2 * i; j < m; j += i) {
|
||||||
|
f[i] -= f[j];
|
||||||
|
}
|
||||||
|
res += f[i];
|
||||||
|
}
|
||||||
|
res = n - 1 - res;
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,541 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,603 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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 bk(4, vector<vector<int>>(4));
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
read(int, u, w, v);
|
||||||
|
--u, --v;
|
||||||
|
if (u > v) swap(u, v);
|
||||||
|
bk[u][v].emplace_back(w);
|
||||||
|
}
|
||||||
|
vector<vector<pii>> e(4);
|
||||||
|
vector<int> w;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
w.emplace_back(accumulate(bk[i][i].begin(), bk[i][i].end(), 0));
|
||||||
|
Edgew(e, i, i, w.size() - 1);
|
||||||
|
for (int j = i + 1; j < 4; ++j) {
|
||||||
|
if (bk[i][j].empty()) continue;
|
||||||
|
int mx = *min_element(bk[i][j].begin(), bk[i][j].end());
|
||||||
|
int sum = accumulate(bk[i][j].begin(), bk[i][j].end(), 0);
|
||||||
|
int m = bk[i][j].size();
|
||||||
|
if (m % 2 == 0) {
|
||||||
|
w.emplace_back(sum - mx);
|
||||||
|
edgew(e, i, j, w.size() - 1);
|
||||||
|
w.emplace_back(mx);
|
||||||
|
edgew(e, i, j, w.size() - 1);
|
||||||
|
} else if (m == 1) {
|
||||||
|
w.emplace_back(sum);
|
||||||
|
edgew(e, i, j, w.size() - 1);
|
||||||
|
} else {
|
||||||
|
w.emplace_back(sum);
|
||||||
|
edgew(e, i, j, w.size() - 1);
|
||||||
|
w.emplace_back(-mx);
|
||||||
|
edgew(e, i, j, w.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int m = w.size();
|
||||||
|
vector<bool> vis(1 << m + 2);
|
||||||
|
auto dfs = [&] (auto dfs, int mask) -> void {
|
||||||
|
if (vis[mask]) return;
|
||||||
|
vis[mask] = true;
|
||||||
|
int v = mask & 3;
|
||||||
|
int visited = mask >> 2;
|
||||||
|
for (auto&& [u, i] : e[v]) {
|
||||||
|
if (visited >> i & 1) continue;
|
||||||
|
dfs(dfs, (visited | 1 << i) << 2 | u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
dfs(dfs, i);
|
||||||
|
}
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < (1 << m + 2); ++i) {
|
||||||
|
if (not vis[i]) continue;
|
||||||
|
int mask = i >> 2;
|
||||||
|
int curr = 0;
|
||||||
|
for (int j = 0; j < m; ++j) {
|
||||||
|
if (mask >> j & 1) {
|
||||||
|
curr += w[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chmax(res, curr);
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,551 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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 mll = MLL<PRIME>;
|
||||||
|
|
||||||
|
map<int, vector<pii>> bk;
|
||||||
|
|
||||||
|
read(int, n, m);
|
||||||
|
vector a(n, vector<int>(m));
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
for (int j = 0; j < m; ++j) {
|
||||||
|
cin >> a[i][j];
|
||||||
|
bk[a[i][j]].emplace_back(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
mll val = 0;
|
||||||
|
mll f = 0, g = 0;
|
||||||
|
mll h = 0, p = 0;
|
||||||
|
vector dp(n, vector<mll>(m));
|
||||||
|
for (auto&& [k, v] : bk) {
|
||||||
|
for (auto&& [i, j] : v) {
|
||||||
|
dp[i][j] = (val + mll(1) * cnt * i * i - 2 * f * i + g + mll(1) * cnt * j * j - 2 * h * j + p) / cnt;
|
||||||
|
}
|
||||||
|
cnt += v.size();
|
||||||
|
for (auto&& [i, j] : v) {
|
||||||
|
val += dp[i][j];
|
||||||
|
f += i;
|
||||||
|
g += i * i;
|
||||||
|
h += j;
|
||||||
|
p += j * j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read(int, i, j);
|
||||||
|
--i, --j;
|
||||||
|
cout << dp[i][j] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,572 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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, k);
|
||||||
|
adj(ch, n);
|
||||||
|
int root;
|
||||||
|
for (int i = 0; i < n - 1; ++i) {
|
||||||
|
read(int, u, v);
|
||||||
|
edge(ch, u, v);
|
||||||
|
if (ch[u].size() > 1) {
|
||||||
|
root = u;
|
||||||
|
} else if (ch[v].size() > 1) {
|
||||||
|
root = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<int> depth(n + 1);
|
||||||
|
depth[0] = -1;
|
||||||
|
int leaf = 0;
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
if (ch[v].size() == 1) {
|
||||||
|
leaf += 1;
|
||||||
|
}
|
||||||
|
depth[v] = depth[pa] + 1;
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, root, 0);
|
||||||
|
}
|
||||||
|
int m = 0;
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> int {
|
||||||
|
vector<int> son;
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
int c = dfs(dfs, u, v);
|
||||||
|
son.emplace_back(c);
|
||||||
|
}
|
||||||
|
if (ch[v].size() == 1) {
|
||||||
|
return depth[v];
|
||||||
|
}
|
||||||
|
sort(son.begin(), son.end());
|
||||||
|
int t = son.size();
|
||||||
|
int s = 0;
|
||||||
|
for (int i = 1; i < t; ++i) {
|
||||||
|
if (son[i] + son[i - 1] - 2 * depth[v] <= k) {
|
||||||
|
m += 1;
|
||||||
|
s += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return son[s];
|
||||||
|
};
|
||||||
|
dfs(dfs, root, 0);
|
||||||
|
}
|
||||||
|
cout << leaf - m << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,696 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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 LCA {
|
||||||
|
vector<int> depth;
|
||||||
|
vector<vector<int>> pa;
|
||||||
|
LCA(const vector<vector<int>>& g, int root = 1) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(root, 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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// WARN: Input could contain multiple edges, but not self loops
|
||||||
|
//
|
||||||
|
// Returns: (BCC count, indices of BCCs of each vertex)
|
||||||
|
//
|
||||||
|
// BCC index starts from 1
|
||||||
|
pair<int, vector<vector<int>>> vbcc(const vector<vector<int>>& ch) {
|
||||||
|
int n = ch.size() - 1;
|
||||||
|
vector<vector<int>> c(n + 1); // a vertex could be contained in multiple vBCCs
|
||||||
|
|
||||||
|
int tm = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
vector<int> low(n + 1), dfn(n + 1);
|
||||||
|
vector<int> stack;
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
int son = 0;
|
||||||
|
low[v] = dfn[v] = ++tm;
|
||||||
|
stack.emplace_back(v);
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
son += 1;
|
||||||
|
if (not dfn[u]) {
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
chmin(low[v], low[u]);
|
||||||
|
if (low[u] >= dfn[v]) {
|
||||||
|
cnt += 1;
|
||||||
|
int z;
|
||||||
|
do {
|
||||||
|
z = popback(stack);
|
||||||
|
c[z].emplace_back(cnt);
|
||||||
|
} while (z != u);
|
||||||
|
c[v].emplace_back(cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chmin(low[v], dfn[u]);
|
||||||
|
}
|
||||||
|
if (pa == 0 and son == 0) {
|
||||||
|
cnt += 1;
|
||||||
|
c[v].emplace_back(cnt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
if (not dfn[i]) {
|
||||||
|
dfs(dfs, i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { cnt, c };
|
||||||
|
}
|
||||||
|
|
||||||
|
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, q);
|
||||||
|
vector<pii> edges;
|
||||||
|
vector<vector<int>> bk;
|
||||||
|
{
|
||||||
|
adj(ch, n);
|
||||||
|
for (int i = 0; i < m; ++i) {
|
||||||
|
read(int, u, v);
|
||||||
|
edges.emplace_back(u, v);
|
||||||
|
edge(ch, u, v);
|
||||||
|
}
|
||||||
|
auto [cnt, c] = vbcc(ch);
|
||||||
|
m = cnt;
|
||||||
|
bk.resize(m + 1);
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
for (int j : c[i]) {
|
||||||
|
bk[j].emplace_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adj(ch, n + m);
|
||||||
|
quick_union qu(n + 1);
|
||||||
|
for (auto&& v : bk) {
|
||||||
|
int m = v.size();
|
||||||
|
for (int i = 1; i < m; ++i) {
|
||||||
|
qu.merge(v[i], v[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<int> w(n + m + 1);
|
||||||
|
for (auto&& [u, v] : edges) {
|
||||||
|
if (qu.connected(u, v)) continue;
|
||||||
|
edge(ch, u, v);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
w[i] = 1;
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= m; ++i) {
|
||||||
|
for (auto&& v : bk[i]) {
|
||||||
|
edge(ch, n + i, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<int> pf(n + m + 1);
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
pf[v] += w[v];
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
pf[u] = pf[v];
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
LCA lca(ch);
|
||||||
|
|
||||||
|
while (q--) {
|
||||||
|
read(int, u, v);
|
||||||
|
int l = lca.query(u, v);
|
||||||
|
cout << pf[u] + pf[v] - 2 * pf[l] + w[l] - 1 << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,560 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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);
|
||||||
|
readvec(ld, p, n);
|
||||||
|
|
||||||
|
adj(ch, n - 1);
|
||||||
|
for (int i = 0; i < n - 1; ++i) {
|
||||||
|
read(int, u, v);
|
||||||
|
edge(ch, u, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<pdd> f(n);
|
||||||
|
ld res = 0;
|
||||||
|
|
||||||
|
vector<int> fa(n);
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
fa[v] = pa;
|
||||||
|
f[v].first = 1 - p[v];
|
||||||
|
f[v].second = 1;
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
f[v].second -= 1 - p[u];
|
||||||
|
}
|
||||||
|
res += f[v].first * f[v].second;
|
||||||
|
};
|
||||||
|
dfs(dfs, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
read(int, q);
|
||||||
|
cout << fixed << setprecision(5);
|
||||||
|
while (q--) {
|
||||||
|
read(int, v);
|
||||||
|
read(ld, np);
|
||||||
|
res -= f[v].first * f[v].second;
|
||||||
|
f[v].first = 1 - np;
|
||||||
|
res += f[v].first * f[v].second;
|
||||||
|
if (fa[v] != -1) {
|
||||||
|
res -= f[fa[v]].first * f[fa[v]].second;
|
||||||
|
f[fa[v]].second += np - p[v];
|
||||||
|
res += f[fa[v]].first * f[fa[v]].second;
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
p[v] = np;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
from sys import stdin
|
||||||
|
input = stdin.readline
|
||||||
|
n = int(input())
|
||||||
|
p = [float(x) for x in input().split(' ')]
|
||||||
|
ch = [[] for _ in range(n)]
|
||||||
|
for _ in range(n - 1):
|
||||||
|
u, v = map(int, input().split(' '))
|
||||||
|
ch[u].append(v)
|
||||||
|
ch[v].append(u)
|
||||||
|
f = [[0., 0.] for _ in range(n)]
|
||||||
|
res = 0.
|
||||||
|
fa = [0] * n
|
||||||
|
def dfs(v, pa):
|
||||||
|
global res
|
||||||
|
fa[v] = pa
|
||||||
|
f[v] = [1 - p[v], 1]
|
||||||
|
for u in ch[v]:
|
||||||
|
if u == pa: continue
|
||||||
|
dfs(u, v)
|
||||||
|
f[v][1] -= 1 - p[u]
|
||||||
|
res += f[v][0] * f[v][1]
|
||||||
|
dfs(0, -1)
|
||||||
|
q = int(input())
|
||||||
|
for _ in range(q):
|
||||||
|
line = input().split(' ')
|
||||||
|
v = int(line[0])
|
||||||
|
np = float(line[1])
|
||||||
|
res -= f[v][0] * f[v][1]
|
||||||
|
f[v][0] = 1 - np
|
||||||
|
res += f[v][0] * f[v][1]
|
||||||
|
if fa[v] != -1:
|
||||||
|
res -= f[fa[v]][0] * f[fa[v]][1]
|
||||||
|
f[fa[v]][1] += np - p[v]
|
||||||
|
res += f[fa[v]][0] * f[fa[v]][1]
|
||||||
|
print(res)
|
||||||
|
p[v] = np
|
||||||
|
|
|
@ -0,0 +1,645 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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 point {
|
||||||
|
T x, y;
|
||||||
|
point() : x(), y() {}
|
||||||
|
point(const pair<T, T>& a) : x(a.first), y(a.second) {}
|
||||||
|
point(const T& x, const T& y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
inline T square() const { return x * x + y * y; }
|
||||||
|
inline ld norm() const { return sqrt(ld(square())); }
|
||||||
|
|
||||||
|
inline point operator+(const point& rhs) const { return point(x + rhs.x, y + rhs.y); }
|
||||||
|
inline point operator-(const point& rhs) const { return point(x - rhs.x, y - rhs.y); }
|
||||||
|
inline point operator+() const { return *this; }
|
||||||
|
inline point operator-() const { return point(-x, -y); }
|
||||||
|
inline point operator*(const T& a) const { return point(x * a, y * a); }
|
||||||
|
inline T operator*(const point& rhs) const { return x * rhs.y - y * rhs.x; }
|
||||||
|
inline point operator/(const T& a) const { return point(x / a, y / a); }
|
||||||
|
inline point& operator+=(const point& rhs) { x += rhs.x, y += rhs.y; return *this; }
|
||||||
|
inline point& operator-=(const point& rhs) { x -= rhs.x, y -= rhs.y; return *this; }
|
||||||
|
inline point& operator*=(const T& a) { x *= a, y *= a; return *this; }
|
||||||
|
inline point& operator/=(const T& a) { x /= a, y /= a; return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const point& rhs) const { return x == rhs.x and y == rhs.y; }
|
||||||
|
inline bool operator!=(const point& rhs) const { return not (*this == rhs); }
|
||||||
|
inline bool operator<(const point& rhs) const { return pair(x, y) < pair(rhs.x, rhs.y); }
|
||||||
|
inline bool operator<=(const point& rhs) const { return *this < rhs or *this == rhs; }
|
||||||
|
inline bool operator>(const point& rhs) const { return not (*this <= rhs); }
|
||||||
|
inline bool operator>=(const point& rhs) const { return not (*this < rhs); }
|
||||||
|
|
||||||
|
static inline ld slope(const point& a, const point& b) {
|
||||||
|
if (a.x == b.x) return INFLL;
|
||||||
|
return ld(a.y - b.y) / (a.x - b.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// distance from point `a` to line `l--r`
|
||||||
|
static inline ld dist(const point& a, const point& l, const point& r) {
|
||||||
|
return area(a, l, r) * 2 / (l - r).norm();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ld area(const point& a, const point& b, const point& c) {
|
||||||
|
return (b - a) * (c - a) / ld(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline istream& operator>>(istream& in, point& a) {
|
||||||
|
return in >> a.x >> a.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline ostream& operator<<(ostream& out, const point& a) {
|
||||||
|
return out << a.x << ' ' << a.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct fractional {
|
||||||
|
T p, q;
|
||||||
|
inline void reduce(void) {
|
||||||
|
if (q < 0) p = -p, q = -q;
|
||||||
|
if (p == 0) q = 1; else { T g = mygcd(abs(p), abs(q)); p /= g; q /= g; }
|
||||||
|
}
|
||||||
|
fractional(void) : p(0), q(1) {}
|
||||||
|
template <typename U>
|
||||||
|
fractional(const U& p) : p(p), q(1) { reduce(); }
|
||||||
|
fractional(const T& p, const T& q) : p(p), q(q) { reduce(); }
|
||||||
|
friend inline fractional operator+(const fractional& lhs) { return *lhs; }
|
||||||
|
friend inline fractional operator-(const fractional& lhs) { return { -lhs.p, lhs.q }; }
|
||||||
|
friend inline fractional operator+(const fractional& lhs, const fractional& rhs) { return { lhs.p * rhs.q + lhs.q * rhs.p, lhs.q * rhs.q }; }
|
||||||
|
friend inline fractional operator-(const fractional& lhs, const fractional& rhs) { return lhs + (-rhs); }
|
||||||
|
friend inline fractional operator*(const fractional& lhs, const fractional& rhs) { return { lhs.p * rhs.p, lhs.q * rhs.q }; }
|
||||||
|
friend inline fractional operator/(const fractional& lhs, const fractional& rhs) { return lhs * fractional(rhs.q, rhs.p); }
|
||||||
|
inline fractional& operator+=(const fractional& rhs) { return *this = *this + rhs; }
|
||||||
|
inline fractional& operator-=(const fractional& rhs) { return *this = *this - rhs; }
|
||||||
|
inline fractional& operator*=(const fractional& rhs) { return *this = *this * rhs; }
|
||||||
|
inline fractional& operator/=(const fractional& rhs) { return *this = *this / rhs; }
|
||||||
|
friend inline bool operator==(const fractional& lhs, const fractional& rhs) { return lhs.p == rhs.p and lhs.q == rhs.q; }
|
||||||
|
friend inline bool operator!=(const fractional& lhs, const fractional& rhs) { return not (lhs == rhs); }
|
||||||
|
friend inline bool operator<(const fractional& lhs, const fractional& rhs) { return (lhs - rhs).p < 0; }
|
||||||
|
friend inline bool operator>=(const fractional& lhs, const fractional& rhs) { return not (lhs < rhs); }
|
||||||
|
friend inline bool operator>(const fractional& lhs, const fractional& rhs) { return lhs >= rhs and lhs != rhs; }
|
||||||
|
friend inline bool operator<=(const fractional& lhs, const fractional& rhs) { return lhs < rhs or lhs == rhs; }
|
||||||
|
friend inline ostream& operator<<(ostream& out, const fractional& x) { return out << x.p << '/' << x.q; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
using fractional = fractional<ll>;
|
||||||
|
using point = point<fractional>;
|
||||||
|
|
||||||
|
read(int, n);
|
||||||
|
read(int, l, r);
|
||||||
|
vector<pair<point, point>> a;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
read(int, x1, y1, x2, y2);
|
||||||
|
a.emplace_back(point(x1, y1), point(x2, y2));
|
||||||
|
}
|
||||||
|
int flag = 1;
|
||||||
|
int res = 0;
|
||||||
|
pair<point, point> prev = a[0];
|
||||||
|
for (auto&& [p1, p2] : a) {
|
||||||
|
auto&& [p_1, p_2] = prev;
|
||||||
|
auto [A, C] = p_1 - p_2;
|
||||||
|
auto [B, D] = (p1 - p_1) - (p2 - p_2);
|
||||||
|
auto dis = [&] (fractional k) {
|
||||||
|
return (B * B + D * D) * k * k + 2 * (A * B + C * D) * k + A * A + C * C;
|
||||||
|
};
|
||||||
|
if (B * B + D * D == 0) {
|
||||||
|
fractional d = dis(0);
|
||||||
|
if (flag == 1 and d <= l * l) {
|
||||||
|
res += 1;
|
||||||
|
flag = 0;
|
||||||
|
}
|
||||||
|
if (d > r * r) {
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fractional k = clamp<fractional>(-(A * B + C * D) / (B * B + D * D), 0, 1);
|
||||||
|
fractional mind = dis(k);
|
||||||
|
fractional maxd = dis(0);
|
||||||
|
if (maxd > r * r) {
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
|
if (flag == 1 and mind <= l * l) {
|
||||||
|
res += 1;
|
||||||
|
flag = 0;
|
||||||
|
}
|
||||||
|
maxd = dis(1);
|
||||||
|
if (maxd > r * r) {
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = { p1, p2 };
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,647 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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)];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LCA {
|
||||||
|
vector<int> depth;
|
||||||
|
vector<vector<int>> pa;
|
||||||
|
LCA(const vector<vector<int>>& g, int root = 1) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(root, 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, m);
|
||||||
|
vector<tiii> edges;
|
||||||
|
vector<vector<pii>> e1(n + 1);
|
||||||
|
for (int i = 0; i < m; ++i) {
|
||||||
|
read(int, u, v, w);
|
||||||
|
edgew(e1, u, v, w);
|
||||||
|
edges.emplace_back(u, v, w);
|
||||||
|
}
|
||||||
|
sort_by_key(edges.begin(), edges.end(), expr(get<2>(t), auto&& t));
|
||||||
|
quick_union qu(n + 1);
|
||||||
|
unordered_set<int, safe_hash> red;
|
||||||
|
vector<vector<pii>> e(n + 1);
|
||||||
|
adj(ch, n);
|
||||||
|
for (auto&& [u, v, w] : edges) {
|
||||||
|
if (qu.connected(u, v)) {
|
||||||
|
red.emplace(u);
|
||||||
|
red.emplace(v);
|
||||||
|
} else {
|
||||||
|
qu.merge(u, v);
|
||||||
|
edgew(e, u, v, w);
|
||||||
|
edge(ch, u, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LCA lca(ch);
|
||||||
|
vector<ll> pf(n + 1);
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
for (auto&& [u, w] : e[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
pf[u] = pf[v] + w;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
}
|
||||||
|
m = red.size();
|
||||||
|
vector dis(m, vector<ll>(n + 1, INFLL));
|
||||||
|
int i = 0;
|
||||||
|
for (auto&& b : red) {
|
||||||
|
dis[i][b] = 0;
|
||||||
|
min_heap<pli> q;
|
||||||
|
q.emplace(0, b);
|
||||||
|
while (q.size()) {
|
||||||
|
auto [d, v] = poptop(q);
|
||||||
|
for (auto&& [u, w] : e1[v]) {
|
||||||
|
if (chmin(dis[i][u], dis[i][v] + w)) {
|
||||||
|
q.emplace(dis[i][u], u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
read(int, q);
|
||||||
|
while (q--) {
|
||||||
|
read(int, u, v);
|
||||||
|
ll res = pf[u] + pf[v] - 2 * pf[lca.query(u, v)];
|
||||||
|
for (int i = 0; i < m; ++i) {
|
||||||
|
chmin(res, dis[i][u] + dis[i][v]);
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,713 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<MLL<MDL1>> power1;
|
||||||
|
static vector<MLL<MDL2>> power2;
|
||||||
|
static const ll b = rd();
|
||||||
|
template <typename _Tp>
|
||||||
|
struct hash_vec {
|
||||||
|
using hash_type = pll;
|
||||||
|
MLL<MDL1> hash1;
|
||||||
|
MLL<MDL2> hash2;
|
||||||
|
vector<_Tp> seq;
|
||||||
|
size_t size() {
|
||||||
|
return seq.size();
|
||||||
|
}
|
||||||
|
void push_back(const _Tp& x) {
|
||||||
|
hash1 = hash1 * b + x;
|
||||||
|
hash2 = hash2 * b + x;
|
||||||
|
seq.push_back(x);
|
||||||
|
}
|
||||||
|
void push_front(const _Tp& x) {
|
||||||
|
size_t length = size();
|
||||||
|
hash1 += x * power1[length];
|
||||||
|
hash2 += x * power2[length];
|
||||||
|
seq.push_front(x);
|
||||||
|
}
|
||||||
|
void pop_back() {
|
||||||
|
_Tp e = seq.back(); seq.pop_back();
|
||||||
|
hash1 = (hash1 - e) / b;
|
||||||
|
hash2 = (hash2 - e) / b;
|
||||||
|
}
|
||||||
|
void pop_front() {
|
||||||
|
_Tp e = seq.front(); seq.pop_front();
|
||||||
|
int length = seq.size();
|
||||||
|
hash1 -= e * power1[length];
|
||||||
|
hash2 -= e * power2[length];
|
||||||
|
}
|
||||||
|
void set(size_t pos, const _Tp& value) {
|
||||||
|
int length = seq.size();
|
||||||
|
int old_value = seq[pos];
|
||||||
|
hash1 += (value - old_value) * power1[length - 1 - pos];
|
||||||
|
hash2 += (value - old_value) * power2[length - 1 - pos];
|
||||||
|
seq[pos] = value;
|
||||||
|
}
|
||||||
|
const _Tp& operator[](size_t pos) {
|
||||||
|
return seq[pos];
|
||||||
|
}
|
||||||
|
hash_type hash() {
|
||||||
|
return {hash1.val, hash2.val};
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
hash1 = 0;
|
||||||
|
hash2 = 0;
|
||||||
|
seq.clear();
|
||||||
|
}
|
||||||
|
hash_vec(size_t maxn) {
|
||||||
|
clear();
|
||||||
|
MLL<MDL1> c1 = power1.size() ? power1.back() * b : 1;
|
||||||
|
MLL<MDL2> c2 = power2.size() ? power2.back() * b : 1;
|
||||||
|
for (int i = power1.size(); i < maxn; ++i) {
|
||||||
|
power1.push_back(c1);
|
||||||
|
power2.push_back(c2);
|
||||||
|
c1 *= b;
|
||||||
|
c2 *= b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) {
|
||||||
|
for (size_t i = 0; i != maxn; ++i) {
|
||||||
|
push_back(init_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct range_hash {
|
||||||
|
vector<pair<MLL<MDL1>, MLL<MDL2>>> hp;
|
||||||
|
range_hash() {}
|
||||||
|
template <typename T>
|
||||||
|
range_hash(const T& vec) {
|
||||||
|
hp.emplace_back();
|
||||||
|
hash_vec<ll> hs(vec.size() + 1);
|
||||||
|
for (auto&& x : vec) {
|
||||||
|
hs.push_back(x);
|
||||||
|
hp.emplace_back(hs.hash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// query hash of subarray [l, r]. Index starts from 0.
|
||||||
|
pair<MLL<MDL1>, MLL<MDL2>> range_query(size_t l, size_t r) const {
|
||||||
|
return {
|
||||||
|
(hp[r + 1].first - hp[l].first * power1[r + 1 - l]),
|
||||||
|
(hp[r + 1].second - hp[l].second * power2[r + 1 - l]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
read(int, n);
|
||||||
|
readvec(string, a, n);
|
||||||
|
readvec(string, b, n);
|
||||||
|
|
||||||
|
int first = -1;
|
||||||
|
vector diff(n, pii(-1, -1));
|
||||||
|
range_hash ba, bb;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
int m = a[i].size();
|
||||||
|
for (int j = 0; j < m; ++j) {
|
||||||
|
if (a[i][j] != b[i][j]) {
|
||||||
|
if (first == -1) {
|
||||||
|
first = i;
|
||||||
|
ba = range_hash(a[i]);
|
||||||
|
bb = range_hash(b[i]);
|
||||||
|
}
|
||||||
|
diff[i].first = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = m - 1; ~j; --j) {
|
||||||
|
if (a[i][j] != b[i][j]) {
|
||||||
|
diff[i].second = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto&& [x, y] = diff[first];
|
||||||
|
int len = y - x + 1;
|
||||||
|
|
||||||
|
auto find_left = [&] (const range_hash& hs, int i, int s) {
|
||||||
|
int l = 1, r = min(s + 1, x + 1);
|
||||||
|
while (l < r) {
|
||||||
|
int mid = l + r + 1 >> 1;
|
||||||
|
if (hs.range_query(s - mid + 1, s) == ba.range_query(x - mid + 1, x)) {
|
||||||
|
l = mid;
|
||||||
|
} else {
|
||||||
|
r = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto find_right = [&] (const range_hash& hs, int i, int s) {
|
||||||
|
int m = a[i].size();
|
||||||
|
int l = 1, r = min<int>(m - s, a[first].size() - y);
|
||||||
|
while (l < r) {
|
||||||
|
int mid = l + r + 1 >> 1;
|
||||||
|
if (hs.range_query(s, s + mid - 1) == ba.range_query(y, y + mid - 1)) {
|
||||||
|
l = mid;
|
||||||
|
} else {
|
||||||
|
r = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ref = ba.range_query(x, y);
|
||||||
|
auto rbf = bb.range_query(x, y);
|
||||||
|
vector<pii> constraint;
|
||||||
|
int l = 0, r = a[first].size() - 1;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
if (i == first) continue;
|
||||||
|
range_hash ca(a[i]), cb(b[i]);
|
||||||
|
if (diff[i].first != -1) {
|
||||||
|
if (ca.range_query(diff[i].first, diff[i].second) != ref or cb.range_query(diff[i].first, diff[i].second) != rbf) {
|
||||||
|
cout << "NO\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chmax(l, x - find_left(ca, i, diff[i].first) + 1);
|
||||||
|
chmin(r, y + find_right(ca, i, diff[i].second) - 1);
|
||||||
|
// deb(i, l, r);
|
||||||
|
// debug(diff[i]);
|
||||||
|
// debug(find_left(i, diff[i].first));
|
||||||
|
// debug(find_right(i, diff[i].second));
|
||||||
|
// } else {
|
||||||
|
// for (int j = 0; j + len - 1 < a[i].size(); ++j) {
|
||||||
|
// if (ca.range_query(j, j + len - 1) == ref) {
|
||||||
|
// // deb(i, j);
|
||||||
|
// // deb(x - find_left(i, j), y + find_right(i, j + len - 1));
|
||||||
|
// constraint.emplace_back(x - find_left(ca, i, j), y + find_right(ca, i, j + len - 1));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rl = l, rr = r;
|
||||||
|
len = r - l + 1;
|
||||||
|
ref = ba.range_query(l, r);
|
||||||
|
auto rawa = a[first].substr(rl, rr - rl + 1);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
range_hash ca(a[i]), cb(b[i]);
|
||||||
|
for (int j = 0; j + len - 1 < a[i].size(); ++j) {
|
||||||
|
if (ca.range_query(j, j + len - 1) == ref) {
|
||||||
|
copy_n(b[first].begin() + rl, len, a[i].begin() + j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a[i] != b[i]) {
|
||||||
|
cout << "NO\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// int rl = x, rr = y;
|
||||||
|
// for (auto&& [p, q] : constraint) {
|
||||||
|
// // deb(p, q);
|
||||||
|
// // deb(l, r);
|
||||||
|
// if (p >= l) {
|
||||||
|
// chmin(rl, p);
|
||||||
|
// } else if (q <= r) {
|
||||||
|
// chmax(rr, q);
|
||||||
|
// } else {
|
||||||
|
// cout << "NO\n";
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
cout << "YES\n";
|
||||||
|
// cout << a[first].substr(rl, rr - rl + 1) << '\n';
|
||||||
|
cout << rawa << '\n';
|
||||||
|
cout << b[first].substr(rl, rr - rl + 1) << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,745 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
|
void 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 LCA {
|
||||||
|
vector<int> depth;
|
||||||
|
vector<vector<int>> pa;
|
||||||
|
LCA(const vector<vector<int>>& g, int root = 1) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(root, 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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Addable_Info_t, typename Tag_t, typename Sequence = std::vector<Addable_Info_t>> class segtree {
|
||||||
|
private:
|
||||||
|
using size_type = uint64_t;
|
||||||
|
using info_type = Addable_Info_t;
|
||||||
|
using tag_type = Tag_t;
|
||||||
|
size_type _max;
|
||||||
|
vector<info_type> d;
|
||||||
|
vector<tag_type> b;
|
||||||
|
void pull(size_type p) {
|
||||||
|
d[p] = d[p * 2] + d[p * 2 + 1];
|
||||||
|
}
|
||||||
|
void push(size_type p, size_type left_len, size_type right_len) {
|
||||||
|
d[p * 2].apply(b[p], left_len), d[p * 2 + 1].apply(b[p], right_len);
|
||||||
|
b[p * 2].apply(b[p]), b[p * 2 + 1].apply(b[p]);
|
||||||
|
b[p] = tag_type();
|
||||||
|
}
|
||||||
|
void set(size_type s, size_type t, size_type p, size_type x, const info_type& c) {
|
||||||
|
if (s == t) {
|
||||||
|
d[p] = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_type m = s + (t - s >> 1);
|
||||||
|
if (s != t) push(p, m - s + 1, t - m);
|
||||||
|
if (x <= m) set(s, m, p * 2, x, c);
|
||||||
|
else set(m + 1, t, p * 2 + 1, x, c);
|
||||||
|
pull(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) {
|
||||||
|
if (l <= s && t <= r) {
|
||||||
|
d[p].apply(c, t - s + 1);
|
||||||
|
b[p].apply(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_type m = s + (t - s >> 1);
|
||||||
|
push(p, m - s + 1, t - m);
|
||||||
|
if (l <= m) range_apply(s, m, p * 2, l, r, c);
|
||||||
|
if (r > m) range_apply(m + 1, t, p * 2 + 1, l, r, c);
|
||||||
|
pull(p);
|
||||||
|
}
|
||||||
|
info_type range_query(size_type s, size_type t, size_type p, size_type l, size_type r) {
|
||||||
|
if (l <= s && t <= r) {
|
||||||
|
return d[p];
|
||||||
|
}
|
||||||
|
size_type m = s + (t - s >> 1);
|
||||||
|
info_type res = {};
|
||||||
|
push(p, m - s + 1, t - m);
|
||||||
|
if (l <= m) res = res + range_query(s, m, p * 2, l, r);
|
||||||
|
if (r > m) res = res + range_query(m + 1, t, p * 2 + 1, l, r);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
void build(const Sequence& a, size_type s, size_type t, size_type p) {
|
||||||
|
if (s == t) {
|
||||||
|
d[p] = a[s];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int m = s + (t - s >> 1);
|
||||||
|
build(a, s, m, p * 2);
|
||||||
|
build(a, m + 1, t, p * 2 + 1);
|
||||||
|
pull(p);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {}
|
||||||
|
segtree(const Sequence& a) : segtree(a.size()) {
|
||||||
|
build(a, {}, _max, 1);
|
||||||
|
}
|
||||||
|
void set(size_type i, const info_type& c) {
|
||||||
|
set({}, _max, 1, i, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void range_apply(size_type l, size_type r, const tag_type& c) {
|
||||||
|
range_apply({}, _max, 1, l, r, c);
|
||||||
|
}
|
||||||
|
void apply(size_type i, const tag_type& c) {
|
||||||
|
range_apply(i, i, c);
|
||||||
|
}
|
||||||
|
info_type range_query(size_type l, size_type r) {
|
||||||
|
return range_query({}, _max, 1, l, r);
|
||||||
|
}
|
||||||
|
info_type query(size_type i) {
|
||||||
|
return range_query(i, i);
|
||||||
|
}
|
||||||
|
Sequence serialize() {
|
||||||
|
Sequence res = {};
|
||||||
|
for (size_type i = 0; i <= _max; ++i) {
|
||||||
|
res.push_back(query(i));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
const vector<info_type>& get_d() {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Tag {
|
||||||
|
ll val = 0;
|
||||||
|
void apply(const Tag& rhs) {
|
||||||
|
val += rhs.val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct Info {
|
||||||
|
ll val = INFLL;
|
||||||
|
void apply(const Tag& rhs, size_t len) {
|
||||||
|
if (val != INFLL)
|
||||||
|
val += rhs.val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Info operator+(const Info &a, const Info &b) {
|
||||||
|
return { min(a.val, b.val) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
read(int, n, L);
|
||||||
|
read(ll, S);
|
||||||
|
readvec1(int, w, n);
|
||||||
|
adj(ch, n);
|
||||||
|
for (int i = 2; i <= n; ++i) {
|
||||||
|
read(int, j);
|
||||||
|
edge(ch, i, j);
|
||||||
|
}
|
||||||
|
LCA lca(ch);
|
||||||
|
vector<int> seq;
|
||||||
|
vector<int> dfn(n + 1);
|
||||||
|
vector<int> sz(n + 1);
|
||||||
|
vector<ll> ps(n + 1);
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
sz[v] = 1;
|
||||||
|
ps[v] = ps[pa] + w[v];
|
||||||
|
dfn[v] = seq.size();
|
||||||
|
seq.emplace_back(v);
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
sz[v] += sz[u];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
}
|
||||||
|
segtree<Info, Tag> val(n);
|
||||||
|
vector<vector<int>> layer(n);
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
layer[lca.depth[i]].emplace_back(i);
|
||||||
|
}
|
||||||
|
vector<vector<int>> bk(n + 1);
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
int l = 1, r = min(lca.depth[i] + 1, L);
|
||||||
|
while (l < r) {
|
||||||
|
int mid = l + r + 1 >> 1;
|
||||||
|
int g = lca.get_kth_ancestor(i, mid);
|
||||||
|
if (ps[i] - ps[g] <= S) {
|
||||||
|
l = mid;
|
||||||
|
} else {
|
||||||
|
r = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bk[lca.get_kth_ancestor(i, l - 1)].emplace_back(i);
|
||||||
|
}
|
||||||
|
vector<ll> dp(n + 1, INFLL);
|
||||||
|
for (int i = n - 1; ~i; --i) {
|
||||||
|
for (auto&& v : layer[i]) {
|
||||||
|
int fa = lca.get_kth_ancestor(v, 1);
|
||||||
|
ll sub = 0;
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == fa) continue;
|
||||||
|
sub += dp[u];
|
||||||
|
}
|
||||||
|
if (w[v] <= S) {
|
||||||
|
chmin(dp[v], sub + 1);
|
||||||
|
}
|
||||||
|
ll low = val.range_query(dfn[v], dfn[v] + sz[v] - 1).val;
|
||||||
|
if (low != INFLL) {
|
||||||
|
chmin(dp[v], sub + low + 1);
|
||||||
|
}
|
||||||
|
if (dp[v] == INFLL) {
|
||||||
|
cout << -1 << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val.set(dfn[v], { 0 });
|
||||||
|
val.range_apply(dfn[v], dfn[v] + sz[v] - 1, { sub - dp[v] });
|
||||||
|
for (auto&& u : bk[v]) {
|
||||||
|
val.set(dfn[u], { INFLL });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << dp[1] << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,627 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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 LCA {
|
||||||
|
vector<int> depth;
|
||||||
|
vector<vector<int>> pa;
|
||||||
|
LCA(const vector<vector<int>>& g, int root = 1) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(root, 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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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, q);
|
||||||
|
adj(ch, n);
|
||||||
|
for (int i = 2; i <= n; ++i) {
|
||||||
|
read(int, j);
|
||||||
|
edge(ch, i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> depth(n + 1, -1);
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
depth[v] = depth[pa] + 1;
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
|
||||||
|
LCA lca(ch);
|
||||||
|
vector<int> idx(n);
|
||||||
|
iota(idx.begin(), idx.end(), 1);
|
||||||
|
sparse_table<int> range_lca(idx.rbegin(), idx.rend(), expr(lca.query(u, v), auto&& u, auto&& v));
|
||||||
|
|
||||||
|
while (q--) {
|
||||||
|
read(int, l, r);
|
||||||
|
int x = range_lca.query(l - 1, r - 1);
|
||||||
|
int choice;
|
||||||
|
if (l + 1 == r) {
|
||||||
|
choice = lca.depth[l] > lca.depth[r] ? r : l;
|
||||||
|
} else {
|
||||||
|
int left = l, right = r;
|
||||||
|
while (right - left >= 2) {
|
||||||
|
int mid = left + right >> 1;
|
||||||
|
if (range_lca.query(left - 1, mid - 1) == x) {
|
||||||
|
right = mid;
|
||||||
|
} else {
|
||||||
|
left = mid + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (left != right) {
|
||||||
|
int other = right == r ? l : r;
|
||||||
|
if (lca.query(left, right) == x and lca.query(left, other) == x) {
|
||||||
|
choice = left;
|
||||||
|
} else {
|
||||||
|
choice = right;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
choice = left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int left = l <= choice - 1 ? range_lca.query(l - 1, choice - 1 - 1) : -1;
|
||||||
|
int right = choice + 1 <= r ? range_lca.query(choice + 1 - 1, r - 1) : -1;
|
||||||
|
if (left != -1 and right != -1) {
|
||||||
|
x = lca.query(left, right);
|
||||||
|
} else if (left != -1) {
|
||||||
|
x = left;
|
||||||
|
} else {
|
||||||
|
x = right;
|
||||||
|
}
|
||||||
|
cout << choice << ' ' << depth[x] << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,592 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int s = n * n;
|
||||||
|
vector dis(3 * s, vector<pll>(3 * s, { INFLL, 0 }));
|
||||||
|
for (int i = 0; i < 3 * s; ++i) {
|
||||||
|
dis[i][i] = { 0, 0 };
|
||||||
|
deque<int> q = { i };
|
||||||
|
while (q.size()) {
|
||||||
|
auto v = popfront(q);
|
||||||
|
// change chip type
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
int u = (v % s) + j * s;
|
||||||
|
if (u == v) continue;
|
||||||
|
if (chmin(dis[i][u], pll(dis[i][v].first + 1, dis[i][v].second + 1))) {
|
||||||
|
q.emplace_back(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int type = (v - (v % s)) / s;
|
||||||
|
int xv = (v % s) / n, yv = (v % s) % n;
|
||||||
|
if (type == 0) {
|
||||||
|
for (int j = 0; j < s; ++j) {
|
||||||
|
int u = type * s + j;
|
||||||
|
int xu = j / n, yu = j % n;
|
||||||
|
if (abs(xv - xu) == 2 and abs(yv - yu) == 1 or abs(xv - xu) == 1 and abs(yv - yu) == 2) {
|
||||||
|
if (chmin(dis[i][u], pll(dis[i][v].first + 1, dis[i][v].second))) {
|
||||||
|
q.emplace_back(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == 1) {
|
||||||
|
for (int j = 0; j < s; ++j) {
|
||||||
|
int u = type * s + j;
|
||||||
|
int xu = j / n, yu = j % n;
|
||||||
|
if (abs(xv - xu) == abs(yv - yu)) {
|
||||||
|
if (chmin(dis[i][u], pll(dis[i][v].first + 1, dis[i][v].second))) {
|
||||||
|
q.emplace_back(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j < s; ++j) {
|
||||||
|
int u = type * s + j;
|
||||||
|
int xu = j / n, yu = j % n;
|
||||||
|
if (xv - xu == 0 or yv - yu == 0) {
|
||||||
|
if (chmin(dis[i][u], pll(dis[i][v].first + 1, dis[i][v].second))) {
|
||||||
|
q.emplace_back(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<int> rev(s);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
for (int j = 0; j < n; ++j) {
|
||||||
|
rev[a[i][j] - 1] = i * n + j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto add = [] (const pll& a, const pll& b) {
|
||||||
|
return pll(a.first + b.first, a.second + b.second);
|
||||||
|
};
|
||||||
|
array<pll, 3> res = {};
|
||||||
|
for (int i = 1; i < s; ++i) {
|
||||||
|
res = {
|
||||||
|
min({ add(res[0], dis[rev[i - 1]][rev[i]]), add(res[1], dis[s + rev[i - 1]][rev[i]]), add(res[2], dis[2 * s + rev[i - 1]][rev[i]]) }),
|
||||||
|
min({ add(res[0], dis[rev[i - 1]][s + rev[i]]), add(res[1], dis[s + rev[i - 1]][s + rev[i]]), add(res[2], dis[2 * s + rev[i - 1]][s + rev[i]]) }),
|
||||||
|
min({ add(res[0], dis[rev[i - 1]][2 * s + rev[i]]), add(res[1], dis[s + rev[i - 1]][2 * s + rev[i]]), add(res[2], dis[2 * s + rev[i - 1]][2 * s + rev[i]]) }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
auto&& [x, y] = *min_element(res.begin(), res.end());
|
||||||
|
cout << x << ' ' << y << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,529 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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 mll = MLL<PRIME>;
|
||||||
|
|
||||||
|
read(int, n, m, b);
|
||||||
|
readvec(int, a, m);
|
||||||
|
mll res = 1;
|
||||||
|
for (int i = 0; i < m; ++i) {
|
||||||
|
int len = i == 0 ? a[i] : a[i] - a[i - 1];
|
||||||
|
mll all = qpow<mll>(b, len);
|
||||||
|
res *= (all * all + all) / 2;
|
||||||
|
}
|
||||||
|
int rem = n - a.back() * 2;
|
||||||
|
res *= qpow<mll>(b, rem);
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,664 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<MLL<MDL1>> power1;
|
||||||
|
static vector<MLL<MDL2>> power2;
|
||||||
|
static const ll b = rd();
|
||||||
|
template <typename _Tp>
|
||||||
|
struct hash_vec {
|
||||||
|
using hash_type = pll;
|
||||||
|
MLL<MDL1> hash1;
|
||||||
|
MLL<MDL2> hash2;
|
||||||
|
vector<_Tp> seq;
|
||||||
|
size_t size() {
|
||||||
|
return seq.size();
|
||||||
|
}
|
||||||
|
void push_back(const _Tp& x) {
|
||||||
|
hash1 = hash1 * b + x;
|
||||||
|
hash2 = hash2 * b + x;
|
||||||
|
seq.push_back(x);
|
||||||
|
}
|
||||||
|
void push_front(const _Tp& x) {
|
||||||
|
size_t length = size();
|
||||||
|
hash1 += x * power1[length];
|
||||||
|
hash2 += x * power2[length];
|
||||||
|
seq.push_front(x);
|
||||||
|
}
|
||||||
|
void pop_back() {
|
||||||
|
_Tp e = seq.back(); seq.pop_back();
|
||||||
|
hash1 = (hash1 - e) / b;
|
||||||
|
hash2 = (hash2 - e) / b;
|
||||||
|
}
|
||||||
|
void pop_front() {
|
||||||
|
_Tp e = seq.front(); seq.pop_front();
|
||||||
|
int length = seq.size();
|
||||||
|
hash1 -= e * power1[length];
|
||||||
|
hash2 -= e * power2[length];
|
||||||
|
}
|
||||||
|
void set(size_t pos, const _Tp& value) {
|
||||||
|
int length = seq.size();
|
||||||
|
int old_value = seq[pos];
|
||||||
|
hash1 += (value - old_value) * power1[length - 1 - pos];
|
||||||
|
hash2 += (value - old_value) * power2[length - 1 - pos];
|
||||||
|
seq[pos] = value;
|
||||||
|
}
|
||||||
|
const _Tp& operator[](size_t pos) {
|
||||||
|
return seq[pos];
|
||||||
|
}
|
||||||
|
hash_type hash() {
|
||||||
|
return {hash1.val, hash2.val};
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
hash1 = 0;
|
||||||
|
hash2 = 0;
|
||||||
|
seq.clear();
|
||||||
|
}
|
||||||
|
hash_vec(size_t maxn) {
|
||||||
|
clear();
|
||||||
|
MLL<MDL1> c1 = power1.size() ? power1.back() * b : 1;
|
||||||
|
MLL<MDL2> c2 = power2.size() ? power2.back() * b : 1;
|
||||||
|
for (int i = power1.size(); i < maxn; ++i) {
|
||||||
|
power1.push_back(c1);
|
||||||
|
power2.push_back(c2);
|
||||||
|
c1 *= b;
|
||||||
|
c2 *= b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) {
|
||||||
|
for (size_t i = 0; i != maxn; ++i) {
|
||||||
|
push_back(init_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct range_hash {
|
||||||
|
vector<pair<MLL<MDL1>, MLL<MDL2>>> hp;
|
||||||
|
template <typename T>
|
||||||
|
range_hash(const T& vec) {
|
||||||
|
hp.emplace_back();
|
||||||
|
hash_vec<ll> hs(vec.size() + 1);
|
||||||
|
for (auto&& x : vec) {
|
||||||
|
hs.push_back(x);
|
||||||
|
hp.emplace_back(hs.hash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// query hash of subarray [l, r]. Index starts from 0.
|
||||||
|
pair<MLL<MDL1>, MLL<MDL2>> range_query(size_t l, size_t r) {
|
||||||
|
return {
|
||||||
|
(hp[r + 1].first - hp[l].first * power1[r + 1 - l]),
|
||||||
|
(hp[r + 1].second - hp[l].second * power2[r + 1 - l]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
vector<int> manacher(const vector<T>& s, const T& never) {
|
||||||
|
vector<T> t = { never };
|
||||||
|
for (auto&& c : s) {
|
||||||
|
t.emplace_back(c);
|
||||||
|
t.emplace_back(never);
|
||||||
|
}
|
||||||
|
int n = t.size();
|
||||||
|
vector<int> r(n);
|
||||||
|
for (int i = 0, j = 0; i < n; ++i) {
|
||||||
|
if (2 * j - i >= 0 && j + r[j] > i) {
|
||||||
|
r[i] = min(r[2 * j - i], j + r[j] - i);
|
||||||
|
}
|
||||||
|
while (i - r[i] >= 0 && i + r[i] < n && t[i - r[i]] == t[i + r[i]]) {
|
||||||
|
r[i] += 1;
|
||||||
|
}
|
||||||
|
if (i + r[i] > j + r[j]) {
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; i += 2) {
|
||||||
|
r[i] = (r[i] - 1) / 2;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < n; i += 2) {
|
||||||
|
r[i] /= 2;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
read(int, n, m);
|
||||||
|
vector a(n, vector<int>(m));
|
||||||
|
vector ps(n, vector(m + 1, array<int, 26>()));
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
for (int j = 0; j < m; ++j) {
|
||||||
|
read(char, c);
|
||||||
|
a[i][j] = c - 'a';
|
||||||
|
ps[i][j + 1] = ps[i][j];
|
||||||
|
ps[i][j + 1][a[i][j]] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ll res = 0;
|
||||||
|
for (int i = 0; i < m; ++i) {
|
||||||
|
vector cnt(n, hash_vec<int>(26));
|
||||||
|
vector<int> cnt_odd(n);
|
||||||
|
for (int j = 0; j < n; ++j) {
|
||||||
|
for (int k = 0; k < 26; ++k) {
|
||||||
|
cnt[j].push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = i; j < m; ++j) {
|
||||||
|
vector<ll> seq(n);
|
||||||
|
vector<int> pos(n);
|
||||||
|
for (int k = 0; k < n; ++k) {
|
||||||
|
int nxt = cnt[k][a[k][j]] + 1;
|
||||||
|
cnt_odd[k] &= ((1 << 26) - 1) ^ (1 << a[k][j]);
|
||||||
|
cnt_odd[k] |= (nxt & 1) << a[k][j];
|
||||||
|
cnt[k].set(a[k][j], nxt);
|
||||||
|
seq[k] = cnt[k].hash1.val xor cnt[k].hash2.val;
|
||||||
|
pos[k] = popcount(cnt_odd[k]) == ((j - i + 1) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ll never = 0;
|
||||||
|
for (int k = 0; k < n; ++k) {
|
||||||
|
if (pos[k] == 0) {
|
||||||
|
seq[k] = --never;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<int> cnt = manacher(seq, -INFLL);
|
||||||
|
for (int k = 0; k < 2 * n + 1; ++k) {
|
||||||
|
if (k % 2 == 0 or pos[k / 2]) {
|
||||||
|
res += cnt[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,582 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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 dinic {
|
||||||
|
struct edge {
|
||||||
|
int to;
|
||||||
|
ll cap;
|
||||||
|
ll flow;
|
||||||
|
int rev;
|
||||||
|
int mark;
|
||||||
|
};
|
||||||
|
vector<vector<edge>> edges;
|
||||||
|
vector<int> layer;
|
||||||
|
vector<bool> vis;
|
||||||
|
dinic(int n) : edges(n + 1), layer(n + 1), vis(n + 1) {}
|
||||||
|
void add_edge(int from, int to, ll cap, int mark = 0, int mark_rev = 0) {
|
||||||
|
edges[from].push_back({ to, cap, 0, int(edges[to].size()), mark });
|
||||||
|
edges[to].push_back({ from, 0, 0, int(edges[from].size() - 1), mark_rev });
|
||||||
|
}
|
||||||
|
bool bfs(int s, int t) {
|
||||||
|
layer.assign(edges.size(), 0);
|
||||||
|
deque<pii> dq;
|
||||||
|
layer[s] = 1;
|
||||||
|
dq.emplace_back(s, 1);
|
||||||
|
while (dq.size()) {
|
||||||
|
popfront(dq, v, l);
|
||||||
|
for (auto&& e : edges[v]) {
|
||||||
|
if (layer[e.to] == 0 and e.cap > e.flow) {
|
||||||
|
layer[e.to] = l + 1;
|
||||||
|
dq.emplace_back(e.to, l + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return layer[t] != 0;
|
||||||
|
}
|
||||||
|
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 layer[e.to] == layer[s] + 1) {
|
||||||
|
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;
|
||||||
|
if (res == cap) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
ll run(int s, int t) {
|
||||||
|
ll res = 0;
|
||||||
|
while (bfs(s, t)) {
|
||||||
|
vis.assign(edges.size(), 0);
|
||||||
|
res += dfs(s, t, LLONG_MAX);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
read(int, n, m);
|
||||||
|
dinic net(n + m + 3);
|
||||||
|
int s = n + m + 1, t = n + m + 2;
|
||||||
|
readvec1(int, a, n);
|
||||||
|
int ep = n;
|
||||||
|
ll tot = 0;
|
||||||
|
for (int i = 1; i <= m; ++i) {
|
||||||
|
read(int, u, v, w);
|
||||||
|
net.add_edge(ep + i, u, INFLL);
|
||||||
|
net.add_edge(ep + i, v, INFLL);
|
||||||
|
net.add_edge(s, ep + i, w);
|
||||||
|
tot += w;
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
net.add_edge(i, t, a[i]);
|
||||||
|
}
|
||||||
|
auto flow = net.run(s, t);
|
||||||
|
cout << tot - flow << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,581 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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 point {
|
||||||
|
T x, y;
|
||||||
|
point() : x(), y() {}
|
||||||
|
point(const pair<T, T>& a) : x(a.first), y(a.second) {}
|
||||||
|
point(const T& x, const T& y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
inline T square() const { return x * x + y * y; }
|
||||||
|
inline ld norm() const { return sqrt(ld(square())); }
|
||||||
|
|
||||||
|
inline point operator+(const point& rhs) const { return point(x + rhs.x, y + rhs.y); }
|
||||||
|
inline point operator-(const point& rhs) const { return point(x - rhs.x, y - rhs.y); }
|
||||||
|
inline point operator+() const { return *this; }
|
||||||
|
inline point operator-() const { return point(-x, -y); }
|
||||||
|
inline point operator*(const T& a) const { return point(x * a, y * a); }
|
||||||
|
inline T operator*(const point& rhs) const { return x * rhs.y - y * rhs.x; }
|
||||||
|
inline point operator/(const T& a) const { return point(x / a, y / a); }
|
||||||
|
inline point& operator+=(const point& rhs) { x += rhs.x, y += rhs.y; return *this; }
|
||||||
|
inline point& operator-=(const point& rhs) { x -= rhs.x, y -= rhs.y; return *this; }
|
||||||
|
inline point& operator*=(const T& a) { x *= a, y *= a; return *this; }
|
||||||
|
inline point& operator/=(const T& a) { x /= a, y /= a; return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const point& rhs) const { return x == rhs.x and y == rhs.y; }
|
||||||
|
inline bool operator!=(const point& rhs) const { return not (*this == rhs); }
|
||||||
|
inline bool operator<(const point& rhs) const { return pair(x, y) < pair(rhs.x, rhs.y); }
|
||||||
|
inline bool operator<=(const point& rhs) const { return *this < rhs or *this == rhs; }
|
||||||
|
inline bool operator>(const point& rhs) const { return not (*this <= rhs); }
|
||||||
|
inline bool operator>=(const point& rhs) const { return not (*this < rhs); }
|
||||||
|
|
||||||
|
static inline ld slope(const point& a, const point& b) {
|
||||||
|
if (a.x == b.x) return INFLL;
|
||||||
|
return ld(a.y - b.y) / (a.x - b.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// distance from point `a` to line `l--r`
|
||||||
|
static inline ld dist(const point& a, const point& l, const point& r) {
|
||||||
|
return area(a, l, r) * 2 / (l - r).norm();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ld area(const point& a, const point& b, const point& c) {
|
||||||
|
return (b - a) * (c - a) / ld(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline istream& operator>>(istream& in, point& a) {
|
||||||
|
return in >> a.x >> a.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline ostream& operator<<(ostream& out, const point& a) {
|
||||||
|
return out << a.x << ' ' << a.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
|
void solve() {
|
||||||
|
using point = point<int128>;
|
||||||
|
|
||||||
|
read(int, n);
|
||||||
|
vector<tiil> a;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
read(int, x, y);
|
||||||
|
read(ll, z);
|
||||||
|
a.emplace_back(x, y, z);
|
||||||
|
}
|
||||||
|
sort_by_key(a.begin(), a.end(), expr(get<0>(t), auto&& t));
|
||||||
|
deque<point> stack;
|
||||||
|
int128 res = 0;
|
||||||
|
for (auto&& [x, y, z] : a) {
|
||||||
|
int m = stack.size();
|
||||||
|
while (m >= 2 and (stack[1] - stack[0]) * point(1, y) < 0) {
|
||||||
|
stack.pop_front();
|
||||||
|
m -= 1;
|
||||||
|
}
|
||||||
|
int128 best = 0;
|
||||||
|
if (m) {
|
||||||
|
chmax(best, stack[0].y - y * stack[0].x);
|
||||||
|
}
|
||||||
|
int128 curr = ll(1) * x * y + best - z;
|
||||||
|
chmax(res, curr);
|
||||||
|
point p(x, curr);
|
||||||
|
while (m >= 2 and (stack[m - 1] - stack[m - 2]) * (p - stack[m - 1]) > 0) {
|
||||||
|
stack.pop_back();
|
||||||
|
m -= 1;
|
||||||
|
}
|
||||||
|
stack.emplace_back(p);
|
||||||
|
}
|
||||||
|
cout << res << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,539 @@
|
||||||
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
|
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
||||||
|
/************* 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
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
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 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(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
|
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
||||||
|
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
||||||
|
#define putvec(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec1(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, " ")); cout << endl;)
|
||||||
|
#define putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define putvec1_eol(a) __AS_PROCEDURE(copy(a.begin() + 1, a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||||
|
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||||
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
|
/* pops */
|
||||||
|
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||||
|
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||||
|
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||||
|
|
||||||
|
/* math */
|
||||||
|
template <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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
||||||
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
|
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||||
|
|
||||||
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
|
if (b == 0) {
|
||||||
|
x = 1, y = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__exgcd(b, a % b, y, x);
|
||||||
|
y -= a / b * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll inverse(ll a, ll b) {
|
||||||
|
ll x, y;
|
||||||
|
__exgcd(a, b, x, y);
|
||||||
|
return mod(x, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<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; }
|
||||||
|
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
||||||
|
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
||||||
|
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
||||||
|
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
||||||
|
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <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);
|
||||||
|
readvec1(int, a, n);
|
||||||
|
adj(ch, n);
|
||||||
|
for (int i = 0; i < n - 1; ++i) {
|
||||||
|
read(int, u, v);
|
||||||
|
edge(ch, u, v);
|
||||||
|
}
|
||||||
|
vector<ll> mx(n + 1);
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
mx[v] = a[v];
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
if (mx[u] > 0) {
|
||||||
|
mx[v] += mx[u];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
}
|
||||||
|
ll res = *max_element(mx.begin() + 1, mx.begin() + n + 1);
|
||||||
|
int cnt = 0;
|
||||||
|
{
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
mx[v] = a[v];
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
if (mx[u] > 0) {
|
||||||
|
mx[v] += mx[u];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mx[v] == res) {
|
||||||
|
cnt += 1;
|
||||||
|
mx[v] = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(dfs, 1, 0);
|
||||||
|
}
|
||||||
|
cout << res * cnt << ' ' << cnt << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
|
||||||
|
assert(false && "incompatible compiler variant detected.");
|
||||||
|
#endif
|
||||||
|
untie;
|
||||||
|
prep();
|
||||||
|
#ifdef SINGLE_TEST_CASE
|
||||||
|
solve();
|
||||||
|
#else
|
||||||
|
read(int, t);
|
||||||
|
for (int i = 0; i < t; ++i) {
|
||||||
|
#ifdef DUMP_TEST_CASE
|
||||||
|
if (t != (TOT_TEST_CASE)) {
|
||||||
|
solve();
|
||||||
|
} else if (i + 1 == (DUMP_TEST_CASE)) {
|
||||||
|
dump();
|
||||||
|
} else {
|
||||||
|
dump_ignore();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
solve();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -1,5 +1,13 @@
|
||||||
4
|
6
|
||||||
4
|
|
||||||
2
|
1 10 1
|
||||||
7
|
|
||||||
69
|
1 2 2
|
||||||
|
|
||||||
|
2 10 3
|
||||||
|
|
||||||
|
2 20 3
|
||||||
|
|
||||||
|
3 1 4
|
||||||
|
|
||||||
|
4 10 4
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
#pragma GCC optimize("Ofast")
|
||||||
/************* This code requires C++17. ***************/
|
/************* This code requires C++17. ***************/
|
||||||
|
|
||||||
#include<bits/stdc++.h>
|
#include<bits/stdc++.h>
|
||||||
|
@ -12,6 +12,8 @@ using namespace std;
|
||||||
constexpr void __() {}
|
constexpr void __() {}
|
||||||
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
|
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
|
||||||
#define __as_typeof(container) remove_reference<decltype(container)>::type
|
#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 */
|
/* type aliases */
|
||||||
#if LONG_LONG_MAX != INT64_MAX
|
#if LONG_LONG_MAX != INT64_MAX
|
||||||
|
@ -177,6 +179,14 @@ template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T,
|
||||||
out << "{" << p.first << ", " << p.second << "}";
|
out << "{" << p.first << ", " << p.second << "}";
|
||||||
return out;
|
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>
|
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...>) {
|
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
|
using swallow = int[]; // guaranties left to right order
|
||||||
|
@ -217,9 +227,9 @@ std::ostream& operator<<(std::ostream& dest, const int128& value) {
|
||||||
}
|
}
|
||||||
template<typename T> void __read(T& x) { cin >> x; }
|
template<typename T> void __read(T& x) { cin >> x; }
|
||||||
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
|
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
|
||||||
#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
#define read(t, ...) __AS_PROCEDURE(argument_type<void(t)>::type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||||
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (auto& x : a) cin >> x;)
|
#define readvec(t, a, n) __AS_PROCEDURE(vector<argument_type<void(t)>::type> a(n); for (auto& x : a) cin >> x;)
|
||||||
#define readvec1(type, a, n) __AS_PROCEDURE(vector<type> a((n) + 1); copy_n(ii<type>(cin), (n), a.begin() + 1);)
|
#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 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 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 putvec_eol(a) __AS_PROCEDURE(copy(a.begin(), a.end(), oi<__as_typeof(a)::value_type>(cout, "\n"));)
|
||||||
|
@ -229,9 +239,24 @@ template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __
|
||||||
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
/* pops */
|
/* pops */
|
||||||
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
template <typename Container>
|
||||||
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
inline auto poptop(Container& q) {
|
||||||
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
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 */
|
/* math */
|
||||||
template <typename return_t>
|
template <typename return_t>
|
||||||
|
@ -243,11 +268,29 @@ return_t qpow(ll b, ll p) {
|
||||||
else return half * half;
|
else return half * half;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define comb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] / fact[k] / fact[(n) - (k)])
|
#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)])
|
#define fastcomb(n, k) ((n) < 0 or (k) < 0 or (n) < (k) ? 0 : fact[n] * factrev[k] * factrev[(n) - (k)])
|
||||||
|
|
||||||
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
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) {
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
x = 1, y = 0;
|
x = 1, y = 0;
|
||||||
|
@ -298,15 +341,15 @@ vector<pii> decompose_prime(int N) {
|
||||||
|
|
||||||
/* string algorithms */
|
/* string algorithms */
|
||||||
vector<int> calc_next(string t) { // pi function of t
|
vector<int> calc_next(string t) { // pi function of t
|
||||||
int n = (int)t.length();
|
int n = (int)t.length();
|
||||||
vector<int> pi(n);
|
vector<int> pi(n);
|
||||||
for (int i = 1; i < n; i++) {
|
for (int i = 1; i < n; i++) {
|
||||||
int j = pi[i - 1];
|
int j = pi[i - 1];
|
||||||
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
||||||
if (t[i] == t[j]) j++;
|
if (t[i] == t[j]) j++;
|
||||||
pi[i] = j;
|
pi[i] = j;
|
||||||
}
|
}
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
vector<int> calc_z(string t) { // z function of t
|
vector<int> calc_z(string t) { // z function of t
|
||||||
int m = t.length();
|
int m = t.length();
|
||||||
|
@ -326,14 +369,14 @@ vector<int> calc_z(string t) { // z function of t
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
vector<int> kmp(string s, string t) { // find all t in s
|
vector<int> kmp(string s, string t) { // find all t in s
|
||||||
string cur = t + '#' + s;
|
string cur = t + '#' + s;
|
||||||
int sz1 = s.size(), sz2 = t.size();
|
int sz1 = s.size(), sz2 = t.size();
|
||||||
vector<int> v;
|
vector<int> v;
|
||||||
vector<int> lps = calc_next(cur);
|
vector<int> lps = calc_next(cur);
|
||||||
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
||||||
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
int period(string s) { // find the length of shortest recurring period
|
int period(string s) { // find the length of shortest recurring period
|
||||||
int n = s.length();
|
int n = s.length();
|
||||||
|
@ -358,11 +401,11 @@ template <ll mdl> struct MLL {
|
||||||
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, 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; }
|
||||||
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
|
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
|
||||||
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
MLL& operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
MLL& operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
MLL& operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
MLL& operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
MLL& operator%=(const MLL& rhs) { return *this = *this % rhs; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <ll mdl>
|
template <ll mdl>
|
||||||
|
|
166
src/bin/test.cc
166
src/bin/test.cc
|
@ -1,5 +1,5 @@
|
||||||
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
// #pragma GCC target("popcnt,lzcnt,abm,bmi,bmi2")
|
||||||
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
|
// #pragma GCC optimize("Ofast")
|
||||||
/************* This code requires C++17. ***************/
|
/************* This code requires C++17. ***************/
|
||||||
|
|
||||||
#include<bits/stdc++.h>
|
#include<bits/stdc++.h>
|
||||||
|
@ -177,6 +177,10 @@ template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T,
|
||||||
out << "{" << p.first << ", " << p.second << "}";
|
out << "{" << p.first << ", " << p.second << "}";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
template<typename T, size_t N> istream& operator>>(istream& in, array<T, N>& a) {
|
||||||
|
for (int i = 0; i < N; ++i) in >> a[i];
|
||||||
|
return in;
|
||||||
|
}
|
||||||
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
|
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...>) {
|
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
|
using swallow = int[]; // guaranties left to right order
|
||||||
|
@ -229,9 +233,24 @@ template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __
|
||||||
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
#define deb(...) debug(make_tuple(__VA_ARGS__))
|
||||||
|
|
||||||
/* pops */
|
/* pops */
|
||||||
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
template <typename Container>
|
||||||
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
inline auto poptop(Container& q) {
|
||||||
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
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 */
|
/* math */
|
||||||
template <typename return_t>
|
template <typename return_t>
|
||||||
|
@ -248,6 +267,9 @@ return_t qpow(ll b, ll p) {
|
||||||
|
|
||||||
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
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) {
|
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
x = 1, y = 0;
|
x = 1, y = 0;
|
||||||
|
@ -298,15 +320,15 @@ vector<pii> decompose_prime(int N) {
|
||||||
|
|
||||||
/* string algorithms */
|
/* string algorithms */
|
||||||
vector<int> calc_next(string t) { // pi function of t
|
vector<int> calc_next(string t) { // pi function of t
|
||||||
int n = (int)t.length();
|
int n = (int)t.length();
|
||||||
vector<int> pi(n);
|
vector<int> pi(n);
|
||||||
for (int i = 1; i < n; i++) {
|
for (int i = 1; i < n; i++) {
|
||||||
int j = pi[i - 1];
|
int j = pi[i - 1];
|
||||||
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
||||||
if (t[i] == t[j]) j++;
|
if (t[i] == t[j]) j++;
|
||||||
pi[i] = j;
|
pi[i] = j;
|
||||||
}
|
}
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
vector<int> calc_z(string t) { // z function of t
|
vector<int> calc_z(string t) { // z function of t
|
||||||
int m = t.length();
|
int m = t.length();
|
||||||
|
@ -326,14 +348,14 @@ vector<int> calc_z(string t) { // z function of t
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
vector<int> kmp(string s, string t) { // find all t in s
|
vector<int> kmp(string s, string t) { // find all t in s
|
||||||
string cur = t + '#' + s;
|
string cur = t + '#' + s;
|
||||||
int sz1 = s.size(), sz2 = t.size();
|
int sz1 = s.size(), sz2 = t.size();
|
||||||
vector<int> v;
|
vector<int> v;
|
||||||
vector<int> lps = calc_next(cur);
|
vector<int> lps = calc_next(cur);
|
||||||
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
||||||
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
int period(string s) { // find the length of shortest recurring period
|
int period(string s) { // find the length of shortest recurring period
|
||||||
int n = s.length();
|
int n = s.length();
|
||||||
|
@ -358,11 +380,11 @@ template <ll mdl> struct MLL {
|
||||||
friend MLL operator%(const MLL& lhs, const MLL& rhs) { return mod(lhs.val - (lhs / rhs).val, 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; }
|
||||||
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
|
friend bool operator!=(const MLL& lhs, const MLL& rhs) { return lhs.val != rhs.val; }
|
||||||
void operator+=(const MLL& rhs) { val = (*this + rhs).val; }
|
void operator+=(const MLL& rhs) { return *this = *this + rhs; }
|
||||||
void operator-=(const MLL& rhs) { val = (*this - rhs).val; }
|
void operator-=(const MLL& rhs) { return *this = *this - rhs; }
|
||||||
void operator*=(const MLL& rhs) { val = (*this * rhs).val; }
|
void operator*=(const MLL& rhs) { return *this = *this * rhs; }
|
||||||
void operator/=(const MLL& rhs) { val = (*this / rhs).val; }
|
void operator/=(const MLL& rhs) { return *this = *this / rhs; }
|
||||||
void operator%=(const MLL& rhs) { val = (*this % rhs).val; }
|
void operator%=(const MLL& rhs) { return *this = *this % rhs; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <ll mdl>
|
template <ll mdl>
|
||||||
|
@ -467,29 +489,81 @@ void dump_ignore() {}
|
||||||
void prep() {
|
void prep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((target("lzcnt")))
|
// WARN: Input could contain multiple edges, but not self loops
|
||||||
|
//
|
||||||
|
// Returns: (BCC count, indices of BCCs of each vertex)
|
||||||
|
//
|
||||||
|
// BCC index starts from 1
|
||||||
|
pair<int, vector<vector<int>>> vbcc(const vector<vector<int>>& ch) {
|
||||||
|
int n = ch.size() - 1;
|
||||||
|
vector<vector<int>> c(n + 1); // a vertex could be contained in multiple vBCCs
|
||||||
|
|
||||||
|
int tm = 0;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
vector<int> low(n + 1), dfn(n + 1);
|
||||||
|
vector<int> stack;
|
||||||
|
auto dfs = [&] (auto dfs, int v, int pa) -> void {
|
||||||
|
int son = 0;
|
||||||
|
low[v] = dfn[v] = ++tm;
|
||||||
|
stack.emplace_back(v);
|
||||||
|
for (auto&& u : ch[v]) {
|
||||||
|
if (u == pa) continue;
|
||||||
|
son += 1;
|
||||||
|
if (not dfn[u]) {
|
||||||
|
dfs(dfs, u, v);
|
||||||
|
chmin(low[v], low[u]);
|
||||||
|
if (low[u] >= dfn[v]) {
|
||||||
|
cnt += 1;
|
||||||
|
int z;
|
||||||
|
do {
|
||||||
|
z = popback(stack);
|
||||||
|
c[z].emplace_back(cnt);
|
||||||
|
} while (z != u);
|
||||||
|
c[v].emplace_back(cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chmin(low[v], dfn[u]);
|
||||||
|
}
|
||||||
|
if (pa == 0 and son == 0) {
|
||||||
|
cnt += 1;
|
||||||
|
c[v].emplace_back(cnt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
if (not dfn[i]) {
|
||||||
|
dfs(dfs, i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { cnt, c };
|
||||||
|
}
|
||||||
|
|
||||||
|
// __attribute__((target("popcnt")))
|
||||||
void solve() {
|
void solve() {
|
||||||
read(int, n, s);
|
read(int, n, m);
|
||||||
readvec(int, a, n);
|
adj(ch, n);
|
||||||
int left = n / 2;
|
while (m--) {
|
||||||
vector<ll> dp(1 << left);
|
read(int, u, v);
|
||||||
unordered_map<ll, ll, safe_hash> cnt;
|
if (u == v) continue;
|
||||||
faster(cnt);
|
edge(ch, u, v);
|
||||||
cnt[0] = 1;
|
|
||||||
for (int i = 1; i < (1 << left); ++i) {
|
|
||||||
int lz = lsp(i);
|
|
||||||
dp[i] = dp[i ^ (1 << lz)] + a[lz];
|
|
||||||
cnt[dp[i]] += 1;
|
|
||||||
}
|
}
|
||||||
int right = n - left;
|
auto [cnt, c] = vbcc(ch);
|
||||||
dp.assign(1 << right, 0);
|
cout << cnt << '\n';
|
||||||
ll res = cnt.count(s) ? cnt[s] : 0;
|
vector<vector<int>> bk(cnt);
|
||||||
for (int i = 1; i < (1 << right); ++i) {
|
// debug(cnt);
|
||||||
int lz = lsp(i);
|
for (int i = 1; i <= n; ++i) {
|
||||||
dp[i] = dp[i ^ (1 << lz)] + a[left + lz];
|
// deb(i, c[i]);
|
||||||
res += cnt.count(s - dp[i]) ? cnt[s - dp[i]] : 0;
|
for (auto&& j : c[i]) {
|
||||||
|
bk[j - 1].emplace_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto&& v : bk) {
|
||||||
|
cout << v.size() << ' ';
|
||||||
|
for (auto&& u : v) {
|
||||||
|
cout << u << ' ';
|
||||||
|
}
|
||||||
|
cout << '\n';
|
||||||
}
|
}
|
||||||
cout << res << '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from math import lcm, ceil, log2
|
from math import lcm, ceil, log2
|
||||||
from random import choice, randint, shuffle
|
from random import choice, randint, shuffle, random
|
||||||
from os import system
|
from os import system
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import io
|
import io
|
||||||
|
@ -7,7 +7,10 @@ import io
|
||||||
PRIME = 998_244_353
|
PRIME = 998_244_353
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
n = 1000000
|
N = 100000
|
||||||
print(n, n)
|
print(N)
|
||||||
for i in range(n):
|
print(*(random() for _ in range(N)))
|
||||||
print(1, 100000)
|
print(*(f'{randint(0, i - 1)} {i}' for i in range(1, N)), sep='\n')
|
||||||
|
print(N)
|
||||||
|
for _ in range(N):
|
||||||
|
print(randint(0, N - 1), random())
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include<bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define isdigit(x) ('0' <= x && x <= '9')
|
||||||
|
template<typename types>
|
||||||
|
inline void read(types &x){
|
||||||
|
x = 0; int f = 1; char c;
|
||||||
|
while ((c = getchar()) && !isdigit(c)) if (c == '-') f = -1;
|
||||||
|
x = c ^ 48;
|
||||||
|
while ((c = getchar()) && isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48);
|
||||||
|
x *= f; return;
|
||||||
|
}
|
||||||
|
template<typename types>
|
||||||
|
void write(types x){
|
||||||
|
if (x < 0) putchar('-'), x = - x;
|
||||||
|
types k = x / 10;
|
||||||
|
if (k) write(k);
|
||||||
|
putchar(x - (k << 3) - (k << 1) | 48);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int MAXN = 500010;
|
||||||
|
const int MAXM = 4000010;
|
||||||
|
|
||||||
|
int n, m;
|
||||||
|
int head[MAXN], to[MAXM], nxt[MAXM], idx = 1;
|
||||||
|
int dfn[MAXN], low[MAXN], timecnt; // timecnt 时间戳记录顺序
|
||||||
|
vector<int> vdcc[MAXN];
|
||||||
|
int vdcc_cnt;
|
||||||
|
stack<int> s;
|
||||||
|
|
||||||
|
inline void addedge(int x, int y){
|
||||||
|
nxt[++idx] = head[x];
|
||||||
|
to[idx] = y;
|
||||||
|
head[x] = idx;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tarjan(int x, int from){
|
||||||
|
dfn[x] = low[x] = ++timecnt;
|
||||||
|
s.push(x);
|
||||||
|
int child = 0;
|
||||||
|
int p;
|
||||||
|
for (int i = head[x]; i; i = nxt[i]){
|
||||||
|
if (i == (from ^ 1)) continue; // 判断来路
|
||||||
|
child++;
|
||||||
|
int y = to[i];
|
||||||
|
if (!dfn[y]){
|
||||||
|
Tarjan(y, i);
|
||||||
|
low[x] = min(low[x], low[y]);
|
||||||
|
if (low[y] >= dfn[x]){ // 找到点双
|
||||||
|
++vdcc_cnt;
|
||||||
|
do{
|
||||||
|
p = s.top(); s.pop();
|
||||||
|
vdcc[vdcc_cnt].push_back(p);
|
||||||
|
} while (p != y); // 弹到子节点
|
||||||
|
vdcc[vdcc_cnt].push_back(x); // 记得把自己加进去
|
||||||
|
}
|
||||||
|
}
|
||||||
|
low[x] = min(low[x], dfn[y]);
|
||||||
|
}
|
||||||
|
if (!child && !from) // 记得特判孤立点
|
||||||
|
vdcc[++vdcc_cnt].push_back(x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
read(n), read(m);
|
||||||
|
int x, y;
|
||||||
|
for (int i = 1; i <= m; ++i){
|
||||||
|
read(x), read(y);
|
||||||
|
if (x != y) addedge(x, y), addedge(y, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i <= n; ++i) if (!dfn[i]) Tarjan(i, 0);
|
||||||
|
|
||||||
|
write(vdcc_cnt), putchar('\n');
|
||||||
|
for (int i = 1; i <= vdcc_cnt; ++i){
|
||||||
|
write(vdcc[i].size()), putchar(' ');
|
||||||
|
for (auto j = vdcc[i].begin(); j != vdcc[i].end(); ++j){
|
||||||
|
write(*j), putchar(' ');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue