QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#729497 | #9569. Subway | ucup-team159# | WA | 1ms | 3880kb | C++20 | 38.4kb | 2024-11-09 17:13:32 | 2024-11-09 17:13:35 |
Judging History
answer
#line 1 "ucup3-16/F/main.cpp"
#define YOSUPO_AVX2_PRAGMA
// #undef YOSUPO_LOCAL
#line 2 "/home/vscode/yosupo-library/src/yosupo/fastio.hpp"
#include <unistd.h>
#include <algorithm>
#include <array>
#include <bit>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#line 2 "/home/vscode/yosupo-library/src/yosupo/internal_type_traits.hpp"
#line 5 "/home/vscode/yosupo-library/src/yosupo/internal_type_traits.hpp"
namespace yosupo {
namespace internal {
template <class T>
using is_signed_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value ||
std::is_same<T, __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int128 =
typename std::conditional<std::is_same<T, __uint128_t>::value ||
std::is_same<T, unsigned __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using make_unsigned_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value,
__uint128_t,
unsigned __int128>;
template <class T>
using is_integral =
typename std::conditional<std::is_integral<T>::value ||
internal::is_signed_int128<T>::value ||
internal::is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
std::is_signed<T>::value) ||
is_signed_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<(is_integral<T>::value &&
std::is_unsigned<T>::value) ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<
is_signed_int128<T>::value,
make_unsigned_int128<T>,
typename std::conditional<std::is_signed<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type>::type;
template <class T>
using is_integral_t = std::enable_if_t<is_integral<T>::value>;
template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
} // namespace internal
} // namespace yosupo
#line 17 "/home/vscode/yosupo-library/src/yosupo/fastio.hpp"
namespace yosupo {
struct Scanner {
public:
Scanner(const Scanner&) = delete;
Scanner& operator=(const Scanner&) = delete;
Scanner(FILE* fp) : fd(fileno(fp)) { line[0] = 127; }
void read() {}
template <class H, class... T> void read(H& h, T&... t) {
bool f = read_single(h);
assert(f);
read(t...);
}
int read_unsafe() { return 0; }
template <class H, class... T> int read_unsafe(H& h, T&... t) {
bool f = read_single(h);
if (!f) return 0;
return 1 + read_unsafe(t...);
}
int close() { return ::close(fd); }
private:
static constexpr int SIZE = 1 << 15;
int fd = -1;
std::array<char, SIZE + 1> line;
int st = 0, ed = 0;
bool eof = false;
bool read_single(std::string& ref) {
if (!skip_space()) return false;
ref = "";
while (true) {
char c = top();
if (c <= ' ') break;
ref += c;
st++;
}
return true;
}
bool read_single(double& ref) {
std::string s;
if (!read_single(s)) return false;
ref = std::stod(s);
return true;
}
template <class T,
std::enable_if_t<std::is_same<T, char>::value>* = nullptr>
bool read_single(T& ref) {
if (!skip_space<50>()) return false;
ref = top();
st++;
return true;
}
template <class T,
internal::is_signed_int_t<T>* = nullptr,
std::enable_if_t<!std::is_same<T, char>::value>* = nullptr>
bool read_single(T& sref) {
using U = internal::to_unsigned_t<T>;
if (!skip_space<50>()) return false;
bool neg = false;
if (line[st] == '-') {
neg = true;
st++;
}
U ref = 0;
do {
ref = 10 * ref + (line[st++] & 0x0f);
} while (line[st] >= '0');
sref = neg ? -ref : ref;
return true;
}
template <class U,
internal::is_unsigned_int_t<U>* = nullptr,
std::enable_if_t<!std::is_same<U, char>::value>* = nullptr>
bool read_single(U& ref) {
if (!skip_space<50>()) return false;
ref = 0;
do {
ref = 10 * ref + (line[st++] & 0x0f);
} while (line[st] >= '0');
return true;
}
bool reread() {
if (ed - st >= 50) return true;
if (st > SIZE / 2) {
std::memmove(line.data(), line.data() + st, ed - st);
ed -= st;
st = 0;
}
if (eof) return false;
auto u = ::read(fd, line.data() + ed, SIZE - ed);
if (u == 0) {
eof = true;
line[ed] = '\0';
u = 1;
}
ed += int(u);
line[ed] = char(127);
return true;
}
char top() {
if (st == ed) {
bool f = reread();
assert(f);
}
return line[st];
}
template <int TOKEN_LEN = 0> bool skip_space() {
while (true) {
while (line[st] <= ' ') st++;
if (ed - st > TOKEN_LEN) return true;
if (st > ed) st = ed;
for (auto i = st; i < ed; i++) {
if (line[i] <= ' ') return true;
}
if (!reread()) return false;
}
}
};
struct Printer {
public:
template <char sep = ' ', bool F = false> void write() {}
template <char sep = ' ', bool F = false, class H, class... T>
void write(const H& h, const T&... t) {
if (F) write_single(sep);
write_single(h);
write<true>(t...);
}
template <char sep = ' ', class... T> void writeln(const T&... t) {
write<sep>(t...);
write_single('\n');
}
Printer(FILE* _fp) : fd(fileno(_fp)) {}
~Printer() { flush(); }
int close() {
flush();
return ::close(fd);
}
void flush() {
if (pos) {
auto res = ::write(fd, line.data(), pos);
assert(res != -1);
pos = 0;
}
}
private:
static std::array<std::array<char, 2>, 100> small;
static std::array<unsigned long long, 20> tens;
static constexpr size_t SIZE = 1 << 15;
int fd;
std::array<char, SIZE> line;
size_t pos = 0;
std::stringstream ss;
template <class T,
std::enable_if_t<std::is_same<char, T>::value>* = nullptr>
void write_single(const T& val) {
if (pos == SIZE) flush();
line[pos++] = val;
}
template <class T,
internal::is_signed_int_t<T>* = nullptr,
std::enable_if_t<!std::is_same<char, T>::value>* = nullptr>
void write_single(const T& val) {
using U = internal::to_unsigned_t<T>;
if (val == 0) {
write_single('0');
return;
}
if (pos > SIZE - 50) flush();
U uval = val;
if (val < 0) {
write_single('-');
uval = -uval;
}
write_unsigned(uval);
}
template <class U,
internal::is_unsigned_int_t<U>* = nullptr,
std::enable_if_t<!std::is_same<char, U>::value>* = nullptr>
void write_single(U uval) {
if (uval == 0) {
write_single('0');
return;
}
if (pos > SIZE - 50) flush();
write_unsigned(uval);
}
static int calc_len(uint64_t x) {
int i = ((63 - std::countl_zero(x)) * 3 + 3) / 10;
if (x < tens[i])
return i;
else
return i + 1;
}
template <class U,
internal::is_unsigned_int_t<U>* = nullptr,
std::enable_if_t<2 >= sizeof(U)>* = nullptr>
void write_unsigned(U uval) {
size_t len = calc_len(uval);
pos += len;
char* ptr = line.data() + pos;
while (uval >= 100) {
ptr -= 2;
memcpy(ptr, small[uval % 100].data(), 2);
uval /= 100;
}
if (uval >= 10) {
memcpy(ptr - 2, small[uval].data(), 2);
} else {
*(ptr - 1) = char('0' + uval);
}
}
template <class U,
internal::is_unsigned_int_t<U>* = nullptr,
std::enable_if_t<4 == sizeof(U)>* = nullptr>
void write_unsigned(U uval) {
std::array<char, 8> buf;
memcpy(buf.data() + 6, small[uval % 100].data(), 2);
memcpy(buf.data() + 4, small[uval / 100 % 100].data(), 2);
memcpy(buf.data() + 2, small[uval / 10000 % 100].data(), 2);
memcpy(buf.data() + 0, small[uval / 1000000 % 100].data(), 2);
if (uval >= 100000000) {
if (uval >= 1000000000) {
memcpy(line.data() + pos, small[uval / 100000000 % 100].data(),
2);
pos += 2;
} else {
line[pos] = char('0' + uval / 100000000);
pos++;
}
memcpy(line.data() + pos, buf.data(), 8);
pos += 8;
} else {
size_t len = calc_len(uval);
memcpy(line.data() + pos, buf.data() + (8 - len), len);
pos += len;
}
}
template <class U,
internal::is_unsigned_int_t<U>* = nullptr,
std::enable_if_t<8 == sizeof(U)>* = nullptr>
void write_unsigned(U uval) {
size_t len = calc_len(uval);
pos += len;
char* ptr = line.data() + pos;
while (uval >= 100) {
ptr -= 2;
memcpy(ptr, small[uval % 100].data(), 2);
uval /= 100;
}
if (uval >= 10) {
memcpy(ptr - 2, small[uval].data(), 2);
} else {
*(ptr - 1) = char('0' + uval);
}
}
template <
class U,
std::enable_if_t<internal::is_unsigned_int128<U>::value>* = nullptr>
void write_unsigned(U uval) {
static std::array<char, 50> buf;
size_t len = 0;
while (uval > 0) {
buf[len++] = char((uval % 10) + '0');
uval /= 10;
}
std::reverse(buf.begin(), buf.begin() + len);
memcpy(line.data() + pos, buf.data(), len);
pos += len;
}
void write_single(const std::string& s) {
for (char c : s) write_single(c);
}
void write_single(const char* s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) write_single(s[i]);
}
template <class T> void write_single(const std::vector<T>& val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write_single(' ');
write_single(val[i]);
}
}
};
inline std::array<std::array<char, 2>, 100> Printer::small = [] {
std::array<std::array<char, 2>, 100> table;
for (int i = 0; i <= 99; i++) {
table[i][1] = char('0' + (i % 10));
table[i][0] = char('0' + (i / 10 % 10));
}
return table;
}();
inline std::array<unsigned long long, 20> Printer::tens = [] {
std::array<unsigned long long, 20> table;
for (int i = 0; i < 20; i++) {
table[i] = 1;
for (int j = 0; j < i; j++) {
table[i] *= 10;
}
}
return table;
}();
} // namespace yosupo
#line 2 "/home/vscode/yosupo-library/src/yosupo/hashmap.hpp"
#include <iterator>
#include <utility>
#line 6 "/home/vscode/yosupo-library/src/yosupo/hashmap.hpp"
#line 2 "/home/vscode/yosupo-library/src/yosupo/hash.hpp"
#line 5 "/home/vscode/yosupo-library/src/yosupo/hash.hpp"
#include <tuple>
#line 7 "/home/vscode/yosupo-library/src/yosupo/hash.hpp"
#include <set>
#include <map>
#line 2 "/home/vscode/yosupo-library/src/yosupo/random.hpp"
#line 6 "/home/vscode/yosupo-library/src/yosupo/random.hpp"
#include <chrono>
#line 8 "/home/vscode/yosupo-library/src/yosupo/random.hpp"
#include <random>
#line 10 "/home/vscode/yosupo-library/src/yosupo/random.hpp"
namespace yosupo {
struct Xoshiro256StarStar {
public:
using result_type = uint64_t;
Xoshiro256StarStar() : Xoshiro256StarStar(0) {}
explicit Xoshiro256StarStar(uint64_t seed) {
// use splitmix64
// Reference: http://xoshiro.di.unimi.it/splitmix64.c
for (int i = 0; i < 4; i++) {
uint64_t z = (seed += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
s[i] = z ^ (z >> 31);
}
}
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return -1; }
result_type operator()() {
const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9;
const uint64_t t = s[1] << 17;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = rotl(s[3], 45);
return result_starstar;
}
private:
// Use xoshiro256**
// Refereces: http://xoshiro.di.unimi.it/xoshiro256starstar.c
static uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
std::array<uint64_t, 4> s;
};
// https://github.com/wangyi-fudan/wyhash
struct WYRand {
public:
using result_type = uint64_t;
explicit WYRand(uint64_t seed) : s(seed) {}
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return -1; }
result_type operator()() {
s += 0x2d358dccaa6c78a5;
auto x = (unsigned __int128)s * (s ^ 0x8bb84b93962eacc9);
return (uint64_t)(x ^ (x >> 64));
}
private:
uint64_t s;
};
using Random = WYRand;
inline Random& global_gen() {
static Random gen(
std::chrono::steady_clock::now().time_since_epoch().count());
return gen;
}
template <class G>
concept random_64 = std::uniform_random_bit_generator<G> &&
std::same_as<uint64_t, std::invoke_result_t<G&>> &&
G::min() == uint64_t(0) && G::max() == uint64_t(-1);
namespace internal {
// random choice from [0, upper]
template <random_64 G> uint64_t uniform_u64(uint64_t upper, G& gen) {
if (!(upper & (upper + 1))) {
// b = 00..0011..11
return gen() & upper;
}
int log = 63 - std::countl_zero(upper);
uint64_t mask = (log == 63) ? ~0ULL : (1ULL << (log + 1)) - 1;
while (true) {
uint64_t r = gen() & mask;
if (r <= upper) return r;
}
}
// random choice from [0, upper], faster than uniform_u64
template <random_64 G> uint64_t random_u64(uint64_t upper, G& gen) {
return (uint64_t)(((unsigned __int128)(upper) + 1) * gen() >> 64);
}
} // namespace internal
template <class T, random_64 G> T uniform(T lower, T upper, G& gen) {
return T(lower +
internal::uniform_u64(uint64_t(upper) - uint64_t(lower), gen));
}
template <class T> T uniform(T lower, T upper) {
return uniform(lower, upper, global_gen());
}
template <class T, random_64 G> T random(T lower, T upper, G& gen) {
return T(lower +
internal::random_u64(uint64_t(upper) - uint64_t(lower), gen));
}
template <class T> T random(T lower, T upper) {
return random(lower, upper, global_gen());
}
template <random_64 G> bool uniform_bool(G& gen) { return gen() & 1; }
inline bool uniform_bool() { return uniform_bool(global_gen()); }
// select 2 elements from [lower, uppper]
template <class T, random_64 G>
std::pair<T, T> uniform_pair(T lower, T upper, G& gen) {
assert(upper - lower >= 1);
T a, b;
do {
a = uniform(lower, upper, gen);
b = uniform(lower, upper, gen);
} while (a == b);
if (a > b) std::swap(a, b);
return {a, b};
}
template <class T> std::pair<T, T> uniform_pair(T lower, T upper) {
return uniform_pair(lower, upper, global_gen());
}
// random value in the interval (0.0, 1.0]
template <class G> inline double open_closed_01(G& gen) {
union {
uint64_t i;
double f;
} u = {0xbff0000000000000 | (gen() >> 12)};
return 2.0 + u.f;
}
inline double open_closed_01() {
return open_closed_01(global_gen());
}
} // namespace yosupo
#line 2 "/home/vscode/yosupo-library/src/yosupo/bitvector.hpp"
#line 7 "/home/vscode/yosupo-library/src/yosupo/bitvector.hpp"
namespace yosupo {
struct BitVec {
public:
BitVec() : BitVec(0) {}
explicit BitVec(size_t _n) : n(_n), d((n + B - 1) / B) {}
size_t size() const { return n; }
void reset() { fill(d.begin(), d.end(), 0); }
void reset(size_t i) { set(i, false); }
BitVec& set() {
for (auto& x : d) {
x = -1ULL;
}
erase_last();
return *this;
}
BitVec& set(size_t i, bool f = true) {
assert(i < n);
if (f) {
d[i / B] |= 1ULL << (i % B);
} else {
d[i / B] &= ~(1ULL << (i % B));
}
return *this;
}
bool test(size_t i) const {
assert(i < n);
return (d[i / B] >> (i % B) & 1) != 0;
}
size_t count() const {
size_t sm = 0;
for (auto x : d) sm += std::popcount(x);
return sm;
}
bool any() const {
for (auto& x : d)
if (x) return true;
return false;
}
int find_first() const {
auto m = d.size();
for (size_t i = 0; i < m; i++) {
if (d[i]) return int(i * B + std::countr_zero(d[i]));
}
return int(size());
}
BitVec& flip() {
op1(std::bit_not<unsigned long long>());
if (n % B) d.back() &= ~(-1ULL << (n % B));
return *this;
}
BitVec& flip(size_t i) {
return set(i, !test(i));
}
// operators
BitVec& operator~() const { return BitVec(*this).flip(); }
BitVec& operator&=(const BitVec& r) {
return op2(r, std::bit_and<unsigned long long>());
}
BitVec& operator|=(const BitVec& r) {
return op2(r, std::bit_or<unsigned long long>());
}
BitVec& operator^=(const BitVec& r) {
return op2(r, std::bit_xor<unsigned long long>());
}
BitVec& operator<<=(const size_t& s) {
auto block = s / B, rem = s % B;
if (d.size() <= block) {
reset();
return *this;
}
for (size_t i = d.size() - 1; i > block; i--) {
if (rem == 0)
d[i] = d[i - block];
else
d[i] = d[i - block] << rem | d[i - block - 1] >> (B - rem);
}
d[block] = d[0] << rem;
erase_last();
fill(d.begin(), d.begin() + block, 0ULL);
return *this;
}
BitVec& operator>>=(const size_t& s) {
auto block = s / B, rem = s % B;
if (d.size() <= block) {
reset();
return *this;
}
for (size_t i = 0; i < d.size() - block - 1; i++) {
if (rem == 0)
d[i] = d[i + block];
else
d[i] = d[i + block + 1] << (B - rem) | d[i + block] >> rem;
}
d[d.size() - block - 1] = d.back() >> rem;
fill(d.begin() + d.size() - block, d.end(), 0ULL);
return *this;
}
BitVec operator&(const BitVec& r) const { return BitVec(*this) &= r; }
BitVec operator|(const BitVec& r) const { return BitVec(*this) |= r; }
BitVec operator^(const BitVec& r) const { return BitVec(*this) ^= r; }
BitVec operator<<(const size_t& s) const { return BitVec(*this) <<= s; }
BitVec operator>>(const size_t& s) const { return BitVec(*this) >>= s; }
bool operator==(const BitVec& r) const { return d == r.d; }
bool operator!=(const BitVec& r) const { return !(d == r.d); }
void push_back(bool f) {
if (n % B == 0) d.push_back(0);
set(n, f);
n++;
}
BitVec substr(size_t st, size_t le) const {
assert(st + le <= n);
BitVec res(le);
size_t i = 0;
while (i < le) {
res.d[i / B] |= d[(st + i) / B] >> ((st + i) % B) << (i % B);
i += std::min(B - i % B, B - (st + i) % B);
}
res.erase_last();
return res;
}
bool substr_match(size_t st, const BitVec& pat) const {
size_t le = pat.size();
assert(st + le <= n);
size_t i = 0;
while (i < le) {
size_t u = std::min({le - i, B - i % B, B - (st + i) % B});
unsigned long long z = pat.d[i / B] >> (i % B) ^ d[(st + i) / B] >> ((st + i) % B);
if (z << (B - u)) return false;
i += u;
}
return true;
}
const std::vector<unsigned long long>& raw_data() const { return d; }
private:
static constexpr size_t B = 64;
size_t n;
std::vector<unsigned long long> d;
void erase_last() {
if (n % B) d.back() &= (unsigned long long)(-1) >> (B - n % B);
}
template <class OP> BitVec& op1(OP op) {
for (auto& x : d) x = op(x);
return *this;
}
template <class OP> BitVec& op2(const BitVec& r, OP op) {
assert(n == r.n);
for (size_t i = 0; i < d.size(); i++) d[i] = op(d[i], r.d[i]);
return *this;
}
};
namespace internal {
// bitvec
template <class H> auto update(const H& h, const BitVec& bs) {
return update(h, bs.raw_data());
}
} // namespace internal
} // namespace yosupo
#line 13 "/home/vscode/yosupo-library/src/yosupo/hash.hpp"
namespace yosupo {
namespace internal {
constexpr int THRESHOLD_HASH = 100;
// Reference: Lemire, Daniel., and Owen, Kaser.
// Strongly Universal String Hashing Is Fast.
inline uint64_t get_seed(int i) {
static std::array<uint64_t, THRESHOLD_HASH> seed = []() {
std::array<uint64_t, THRESHOLD_HASH> _seed;
for (auto& x : _seed) {
x = yosupo::uniform(uint64_t(0), uint64_t(-1));
}
return _seed;
}();
static std::vector<uint64_t> long_seed;
if (i < THRESHOLD_HASH) return seed[i];
while (THRESHOLD_HASH + int(long_seed.size()) <= i) {
long_seed.push_back(yosupo::uniform(uint64_t(0), uint64_t(-1)));
}
return long_seed[i - THRESHOLD_HASH];
}
struct DynHasher32 {
int len = 0;
uint64_t v = get_seed(0);
DynHasher32 update32(uint32_t x) const {
return DynHasher32{len + 1, v + x * get_seed(len)};
}
DynHasher32 to_dyn() const { return *this; }
uint32_t digest() const { return uint32_t(v >> 32); }
};
template <int I = 1> struct Hasher32 {
uint64_t v = get_seed(0);
Hasher32<I + 1> update32(uint32_t x) const {
return Hasher32<I + 1>{v + x * get_seed(I)};
}
DynHasher32 to_dyn() const { return DynHasher32{I, v}; }
uint32_t digest() const { return uint32_t(v >> 32); }
};
// integer
template <class H,
class T,
is_integral_t<T>* = nullptr,
std::enable_if_t<4 >= sizeof(T)>* = nullptr>
auto update(const H& h, const T& x) {
return h.update32(uint32_t(x));
}
template <class H,
class T,
is_integral_t<T>* = nullptr,
std::enable_if_t<sizeof(T) == 8>* = nullptr>
auto update(const H& h, const T& x) {
return update(update(h, uint32_t(x)), uint32_t(uint64_t(x) >> 32));
}
template <class H,
class T,
is_integral_t<T>* = nullptr,
std::enable_if_t<sizeof(T) == 16>* = nullptr>
auto update(const H& h, const T& x) {
return update(update(h, uint64_t(x)), uint64_t((__uint128_t)(x) >> 64));
}
// pair
template <class H, class S, class T>
auto update(const H& h, const std::pair<S, T>& x) {
return update(update(h, x.first), x.second);
}
// tuple
template <int I,
class H,
class T,
std::enable_if_t<(I == std::tuple_size<T>::value)>* = nullptr>
auto update(const H& h, const T&) {
return h;
}
template <int I = 0,
class H,
class T,
std::enable_if_t<(I != std::tuple_size<T>::value)>* = nullptr>
auto update(const H& h, const T& x) {
return update<I + 1>(update(h, std::get<I>(x)), x);
}
// array
template <int I = 0,
class H,
class T,
int N>
auto update(const H& h, const std::array<T, N>& x) {
return I == N ? h : update<I + 1>(update(h, x[I]), x);
}
// vector
template <class H, class T> auto update(const H& h, const std::vector<T>& v) {
auto h2 = update(h, v.size()).to_dyn();
for (const auto& x : v) {
h2 = update(h2, x);
}
return h2;
}
// set
template <class H, class T> auto update(const H& h, const std::set<T>& s) {
auto h2 = update(h, s.size()).to_dyn();
for (const auto& x : s) {
h2 = update(h2, x);
}
return h2;
}
// map
template <class H, class T, class U> auto update(const H& h, const std::map<T, U>& m) {
auto h2 = update(h, m.size()).to_dyn();
for (const auto& x : m) {
h2 = update(h2, x);
}
return h2;
}
} // namespace internal
template <class T> struct UniversalHash32 {
uint32_t operator()(const T& x) {
return internal::update(internal::Hasher32<>{}, x).digest();
}
};
} // namespace yosupo
#line 8 "/home/vscode/yosupo-library/src/yosupo/hashmap.hpp"
namespace yosupo {
template <class K, class D, class H = UniversalHash32<K>>
struct IncrementalHashMap {
public:
using Data = std::pair<K, D>;
private:
struct Iterator {
public:
using difference_type = int;
using value_type = Data;
using pointer = Data*;
using reference = Data&;
using iterator_category = std::forward_iterator_tag;
IncrementalHashMap& _mp;
unsigned int _pos;
Iterator(IncrementalHashMap& mp, unsigned int pos)
: _mp(mp), _pos(pos) {}
std::pair<K, D>& operator*() const { return _mp.data[_pos]; }
std::pair<K, D>* operator->() const { return &_mp.data[_pos]; }
Iterator& operator++() {
_pos = _mp.next_bucket(_pos + 1);
return *this;
}
Iterator operator++(int) {
auto result = *this;
++*this;
return result;
}
bool operator==(const Iterator& rhs) const { return _pos == rhs._pos; }
bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
};
public:
IncrementalHashMap(size_t s)
: mask((1 << s) - 1), filled(0), used(mask + 1), data(mask + 1) {}
IncrementalHashMap() : IncrementalHashMap(2) {}
Iterator begin() { return Iterator(*this, next_bucket(0)); }
Iterator end() { return Iterator(*this, mask + 1); }
using iterator = Iterator;
D& operator[](const K& k) {
unsigned int i = H()(k) & mask;
while (used[i] && data[i].first != k) {
i = (i + 1) & mask;
}
if (!used[i]) {
if (filled * 2 > mask) {
rehash();
return (*this)[k];
}
filled++;
used[i] = true;
data[i] = {k, D()};
}
return data[i].second;
}
Iterator find(const K& k) {
unsigned int i = H()(k) & mask;
while (used[i] && data[i].first != k) {
i = (i + 1) & mask;
}
if (!used[i]) return end();
return Iterator(*this, i);
}
size_t count(const K& k) {
return find(k) == end() ? 0 : 1;
}
size_t size() const { return filled; }
private:
unsigned int mask, filled; // data.size() == 1 << s
std::vector<bool> used;
std::vector<Data> data;
void rehash() {
unsigned int pmask = mask;
mask = mask * 2 + 1;
filled = 0;
auto pused = std::exchange(used, std::vector<bool>(mask + 1));
auto pdata = std::exchange(data, std::vector<Data>(mask + 1));
for (unsigned int i = 0; i <= pmask; i++) {
if (pused[i]) {
(*this)[pdata[i].first] = pdata[i].second;
}
}
}
unsigned int next_bucket(unsigned int i) const {
while (i <= mask && !used[i]) i++;
return i;
}
};
} // namespace yosupo
#line 6 "ucup3-16/F/main.cpp"
using namespace yosupo;
#line 2 "ucup3-16/F/base.hpp"
#ifdef YOSUPO_AVX2_PRAGMA
#line 5 "ucup3-16/F/base.hpp"
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#endif
#line 11 "ucup3-16/F/base.hpp"
#include <bitset>
#line 13 "ucup3-16/F/base.hpp"
#include <cmath>
#include <cstdio>
#line 16 "ucup3-16/F/base.hpp"
#include <iostream>
#line 18 "ucup3-16/F/base.hpp"
#include <queue>
#include <ranges>
#line 24 "ucup3-16/F/base.hpp"
using std::abs, std::pow, std::sqrt;
using std::array, std::vector, std::string, std::queue, std::deque;
using std::countl_zero, std::countl_one, std::countr_zero, std::countr_one;
using std::istream, std::ostream, std::cerr, std::endl;
using std::min, std::max, std::swap;
using std::pair, std::tuple, std::bitset;
using std::popcount;
using std::priority_queue, std::set, std::multiset, std::map;
using std::views::iota, std::views::reverse;
namespace ranges = std::ranges;
using ranges::sort, ranges::copy_n;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
#ifdef YOSUPO_LOCAL
inline ostream& operator<<(ostream& os, __int128_t x) {
if (x < 0) {
os << "-";
x *= -1;
}
if (x == 0) {
return os << "0";
}
string s;
while (x) {
s += char(x % 10 + '0');
x /= 10;
}
ranges::reverse(s);
return os << s;
}
inline ostream& operator<<(ostream& os, __uint128_t x) {
if (x == 0) {
return os << "0";
}
string s;
while (x) {
s += char(x % 10 + '0');
x /= 10;
}
ranges::reverse(s);
return os << s;
}
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> ostream& operator<<(ostream& os, const V<T>& v);
template <class T> ostream& operator<<(ostream& os, const deque<T>& v);
template <class T, size_t N>
ostream& operator<<(ostream& os, const array<T, N>& a);
template <class T> ostream& operator<<(ostream& os, const set<T>& s);
template <class T, class U>
ostream& operator<<(ostream& os, const map<T, U>& m);
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
return os << "P(" << p.first << ", " << p.second << ")";
}
template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
os << "[";
bool f = false;
for (auto d : v) {
if (f) os << ", ";
f = true;
os << d;
}
return os << "]";
}
template <class T> ostream& operator<<(ostream& os, const deque<T>& v) {
os << "[";
bool f = false;
for (auto d : v) {
if (f) os << ", ";
f = true;
os << d;
}
return os << "]";
}
template <class T, size_t N>
ostream& operator<<(ostream& os, const array<T, N>& a) {
os << "[";
bool f = false;
for (auto d : a) {
if (f) os << ", ";
f = true;
os << d;
}
return os << "]";
}
template <class T> ostream& operator<<(ostream& os, const set<T>& s) {
os << "{";
bool f = false;
for (auto d : s) {
if (f) os << ", ";
f = true;
os << d;
}
return os << "}";
}
template <class T> ostream& operator<<(ostream& os, const multiset<T>& s) {
os << "{";
bool f = false;
for (auto d : s) {
if (f) os << ", ";
f = true;
os << d;
}
return os << "}";
}
template <class T, class U>
ostream& operator<<(ostream& os, const map<T, U>& s) {
os << "{";
bool f = false;
for (auto p : s) {
if (f) os << ", ";
f = true;
os << p.first << ": " << p.second;
}
return os << "}";
}
struct PrettyOS {
ostream& os;
bool first;
template <class T> auto operator<<(T&& x) {
if (!first) os << ", ";
first = false;
os << x;
return *this;
}
};
template <class... T> void dbg0(T&&... t) {
(PrettyOS{cerr, true} << ... << t);
}
#define dbg(...) \
do { \
cerr << __LINE__ << " : " << #__VA_ARGS__ << " = "; \
dbg0(__VA_ARGS__); \
cerr << endl; \
} while (false);
#else
#define dbg(...)
#endif
#line 9 "ucup3-16/F/main.cpp"
Scanner sc = Scanner(stdin);
Printer pr = Printer(stdout);
namespace noimi {
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define ov3(a, b, c, name, ...) name
#define rep0(n) for (ll aaaaa = 0; aaaaa < n; ++aaaaa)
#define rep1(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, a, b) for (ll i = (a); i < (b); i++)
#define rep(...) ov3(__VA_ARGS__, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for (ll i = (a) - 1; i >= (b); i--)
#define all(a) begin(a), end(a)
#define si(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back
bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; }
const int INF = int(1e9 + 100);
const ll INFL = ll(3e18 + 100);
struct lctree {
struct line {
ll a, b;
line() : a(0), b(INFL) {}
line(ll a, ll b) : a(a), b(b) {}
ll get(ll x) { return a * x + b; }
inline bool over(line r, ll x) { return get(x) < r.get(x); }
};
int n;
vector<ll> x;
vector<line> seg;
lctree() {}
lctree(const vector<ll>& _x) : x(_x) {
sort(all(x));
int n2 = si(x);
n = 1;
while (n < n2) n <<= 1;
x.resize(n);
rep(i, n2, n) x[i] = x[n2 - 1];
seg = vector<line>(n * 2);
}
void upd(line L, int i, int l, int r) {
while (true) {
int mid = l + r >> 1;
bool lov = L.over(seg[i], x[l]);
bool rov = L.over(seg[i], x[r - 1]);
if (lov == rov) {
if (lov) swap(seg[i], L);
return;
}
bool mov = L.over(seg[i], x[mid]);
if (mov) swap(seg[i], L);
if (lov != mov) {
i = (i << 1), r = mid;
} else {
i = (i << 1) + 1, l = mid;
}
}
}
void upd(line L, unsigned i) {
int ub = std::bit_width(i) - 1;
int l = (n >> ub) * (i - (1 << ub));
int r = l + (n >> ub);
upd(L, i, l, r);
}
void update(ll a, ll b) { upd(line(a, b), 1, 0, n); }
void update_segment(ll l, ll r, ll a, ll b) {
l = lb(x, l) + n, r = lb(x, r) + n;
line L(a, b);
for (; l < r; l >>= 1, r >>= 1) {
if (l & 1) upd(L, l++);
if (r & 1) upd(L, --r);
}
}
ll query(ll t) {
ll k = lb(x, t);
k += n;
ll res = seg[k].get(t);
while (k > 1) {
k >>= 1;
chmin(res, seg[k].get(t));
}
return res;
}
};
}
int main() {
int n, lines;
sc.read(n, lines);
V<ll> a(lines), b(lines);
for (int i : iota(0, lines)) {
sc.read(a[i]);
}
for (int i : iota(0, lines)) {
sc.read(b[i]);
}
using P = pair<int, int>;
VV<P> ps(n); // line, lid
VV<int> vs(lines);
VV<ll> ws(lines);
for (int i : iota(0, lines)) {
int k;
sc.read(k);
vs[i].resize(k);
ws[i].resize(k - 1);
sc.read(vs[i][0]);
vs[i][0]--;
for (int j : iota(0, k - 1)) {
sc.read(ws[i][j], vs[i][j + 1]);
vs[i][j + 1]--;
}
for (int j : iota(0, k)) {
ps[vs[i][j]].push_back({i, j});
}
}
for (int i : iota(0, n)) {
sort(ps[i].begin(), ps[i].end(), [&](P x, P y) {
return a[x.first] < a[y.first];
});
}
dbg(ps);
IncrementalHashMap<P, int> vl2vid;
for (int i : iota(0, n)) {
for (int j : iota(0, int(ps[i].size()))) {
vl2vid[{i, ps[i][j].first}] = j;
}
}
using S = pair<bool, P>; // type, (v, vid)
using Q = pair<ll, S>;
priority_queue<Q, V<Q>, std::greater<Q>> que;
const ll INF = TEN(18) + TEN(10);
VV<ll> dist(n);
for (int i : iota(0, n)) {
dist[i].assign(ps[i].size(), INF);
}
V<int> cht(n);
V<ll> cht_dist(n, INF);
V<noimi::lctree> chts;
for (int i : iota(0, n)) {
V<ll> x;
for (int j : iota(0, int(ps[i].size()))) {
x.push_back(b[ps[i][j].first]);
}
chts.push_back(noimi::lctree(x));
}
auto check = [&](int v) {
if (cht[v] == int(ps[v].size())) return;
int to = ps[v][cht[v]].first;
// // SLOW
// ll mi = INF;
// for (int i : iota(0, int(ps[v].size()))) {
// int from = ps[v][i].first;
// mi = min(mi, dist[v][i] + b[from] * a[to]);
// }
ll mi = chts[v].query(a[to]);
if (cht_dist[v] <= mi) return;
cht_dist[v] = mi;
que.push({mi, {1, {v, cht[v]}}});
};
auto upd = [&](P p, ll di) { // p = (v, vid)
if (dist[p.first][p.second] <= di) return;
dist[p.first][p.second] = di;
chts[p.first].update(b[ps[p.first][p.second].first], di);
que.push({di, {0, p}});
check(p.first);
};
for (int i : iota(0, int(ps[0].size()))) {
upd({0, i}, 0);
}
V<ll> ans(n, INF);
while (que.size()) {
auto [di, s] = que.top();
auto [type, p] = s;
auto [v, id] = p;
que.pop();
ans[v] = min(ans[v], di);
if (type == 1) {
if (id != cht[v]) continue;
cht[v]++;
cht_dist[v] = INF;
upd(p, di);
check(v);
} else {
// station
auto [line, index] = ps[v][id];
if (index + 1 < int(vs[line].size())) {
int nv = vs[line][index + 1];
int nvid = vl2vid[{nv, line}];
upd({nv, nvid}, di + ws[line][index]);
}
}
}
for (int i : iota(1, n)) {
if (i > 1) pr.write(' ');
pr.write(ans[i]);
}
pr.writeln();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3692kb
input:
6 3 1 5 1 5 5 1 3 1 2 2 3 3 3 5 1 2 1 4 3 3 4 5 4 6
output:
2 5 21 14 18
result:
ok 5 number(s): "2 5 21 14 18"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3664kb
input:
6 3 1 5 1 5 5 1 5 1 2 2 100 3 100 6 1 4 5 1 100 2 4 3 100 5 1 4 2 3 1 5
output:
2 31 43 37 136
result:
ok 5 number(s): "2 31 43 37 136"
Test #3:
score: 0
Accepted
time: 0ms
memory: 3880kb
input:
5 9 278281 70119 511791 834898 25300 63487 609134 236836 394497 835557 287345 579404 879128 636344 306393 569430 152565 47119 2 3 823004250 4 2 1 25427550 3 2 1 15849621 3 2 1 701911826 5 3 5 679672631 3 907176714 2 2 1 817370554 2 2 3 697987914 2 2 4 873900795 2 2 1 814305954 5
output:
817370554 15849621 80811085745 701911826
result:
ok 4 number(s): "817370554 15849621 80811085745 701911826"
Test #4:
score: -100
Wrong Answer
time: 0ms
memory: 3624kb
input:
5 10 436148 103565 528276 212202 680282 92724 609031 560815 80390 406327 546832 581372 731920 348686 791433 98906 112247 118131 361076 724950 4 1 213029090 4 415633732 5 581145231 3 2 4 306227294 2 2 1 713116112 4 2 3 99672714 5 2 3 975143846 1 5 4 249118026 5 689334413 1 597093740 2 553624319 3 3 4...
output:
129 765908995 213029090 628662822
result:
wrong answer 1st numbers differ - expected: '597093740', found: '129'