QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#612046 | #9425. Generated String | ucup-team4435 | TL | 559ms | 43228kb | C++20 | 67.5kb | 2024-10-05 03:03:07 | 2024-10-13 20:42:37 |
Judging History
answer
#pragma GCC optimize("Ofast")
#include "bits/stdc++.h"
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;
int Bit(int mask, int b) { return (mask >> b) & 1; }
template<class T>
bool ckmin(T &a, const T &b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<class T>
bool ckmax(T &a, const T &b) {
if (b > a) {
a = b;
return true;
}
return false;
}
#include <algorithm>
#include <bit>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <functional>
#include <numeric>
#include <type_traits>
#include <vector>
#ifndef __OY_LINUXIO__
#define __OY_LINUXIO__
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <string>
#include <vector>
#ifdef __unix__
#include <sys/mman.h>
#include <sys/stat.h>
#endif
#if __cpp_constexpr >= 201907L
#define CONSTEXPR20 constexpr
#define INLINE20 constexpr
#else
#define CONSTEXPR20
#define INLINE20 inline
#endif
#define cin OY::LinuxIO::InputHelper<>::get_instance()
#define cout OY::LinuxIO::OutputHelper::get_instance()
#define endl '\n'
#ifndef INPUT_FILE
#define INPUT_FILE "in.txt"
#endif
#ifndef OUTPUT_FILE
#define OUTPUT_FILE "out.txt"
#endif
namespace OY {
namespace LinuxIO {
static constexpr size_t INPUT_BUFFER_SIZE = 1 << 26, OUTPUT_BUFFER_SIZE = 1 << 20;
#ifdef OY_LOCAL
static constexpr char input_file[] = INPUT_FILE, output_file[] = OUTPUT_FILE;
#else
static constexpr char input_file[] = "", output_file[] = "";
#endif
template <typename U, size_t E>
struct TenPow {
static constexpr U value = TenPow<U, E - 1>::value * 10;
};
template <typename U>
struct TenPow<U, 0> {
static constexpr U value = 1;
};
struct InputPre {
uint32_t m_data[0x10000];
CONSTEXPR20 InputPre() {
std::fill(m_data, m_data + 0x10000, -1);
for (size_t i = 0, val = 0; i != 10; i++)
for (size_t j = 0; j != 10; j++) m_data[0x3030 + i + (j << 8)] = val++;
}
};
struct OutputPre {
uint32_t m_data[10000];
CONSTEXPR20 OutputPre() {
uint32_t *c = m_data;
for (size_t i = 0; i != 10; i++)
for (size_t j = 0; j != 10; j++)
for (size_t k = 0; k != 10; k++)
for (size_t l = 0; l != 10; l++) *c++ = i + (j << 8) + (k << 16) + (l << 24) + 0x30303030;
}
};
template <size_t MMAP_SIZE = 1 << 30>
struct InputHelper {
static INLINE20 InputPre pre{};
struct stat m_stat;
char *m_p, *m_c, *m_end;
InputHelper(FILE *file = stdin) {
#ifdef __unix__
auto fd = fileno(file);
fstat(fd, &m_stat);
m_c = m_p = (char *)mmap(nullptr, m_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
m_end = m_p + m_stat.st_size;
#else
uint32_t size = fread(m_c = m_p = new char[INPUT_BUFFER_SIZE], 1, INPUT_BUFFER_SIZE, file);
m_end = m_p + size;
#endif
}
static InputHelper<MMAP_SIZE> &get_instance() {
static InputHelper<MMAP_SIZE> s_obj(*input_file ? fopen(input_file, "rt") : stdin);
return s_obj;
}
template <typename Tp, typename std::enable_if<std::is_unsigned<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
InputHelper &operator>>(Tp &x) {
x = 0;
while (!isdigit(*m_c)) m_c++;
x = *m_c++ ^ '0';
while (~pre.m_data[*reinterpret_cast<uint16_t *&>(m_c)]) x = x * 100 + pre.m_data[*reinterpret_cast<uint16_t *&>(m_c)++];
if (isdigit(*m_c)) x = x * 10 + (*m_c++ ^ '0');
return *this;
}
template <typename Tp, typename std::enable_if<std::is_signed<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
InputHelper &operator>>(Tp &x) {
typename std::make_unsigned<Tp>::type t{};
bool sign{};
while (!isdigit(*m_c)) sign = (*m_c++ == '-');
t = *m_c++ ^ '0';
while (~pre.m_data[*reinterpret_cast<uint16_t *&>(m_c)]) t = t * 100 + pre.m_data[*reinterpret_cast<uint16_t *&>(m_c)++];
if (isdigit(*m_c)) t = t * 10 + (*m_c++ ^ '0');
x = sign ? -t : t;
return *this;
}
InputHelper &operator>>(char &x) {
while (*m_c <= ' ') m_c++;
x = *m_c++;
return *this;
}
InputHelper &operator>>(std::string &x) {
while (*m_c <= ' ') m_c++;
char *c = m_c;
while (*c > ' ') c++;
x.assign(m_c, c - m_c), m_c = c;
return *this;
}
InputHelper &operator>>(std::string_view &x) {
while (*m_c <= ' ') m_c++;
char *c = m_c;
while (*c > ' ') c++;
x = std::string_view(m_c, c - m_c), m_c = c;
return *this;
}
};
struct OutputHelper {
static INLINE20 OutputPre pre{};
FILE *m_file;
char m_p[OUTPUT_BUFFER_SIZE], *m_c, *m_end;
OutputHelper(FILE *file = stdout) {
m_file = file;
m_c = m_p, m_end = m_p + OUTPUT_BUFFER_SIZE;
}
~OutputHelper() { flush(); }
static OutputHelper &get_instance() {
static OutputHelper s_obj(*output_file ? fopen(output_file, "wt") : stdout);
return s_obj;
}
void flush() { fwrite(m_p, 1, m_c - m_p, m_file), m_c = m_p; }
OutputHelper &operator<<(char x) {
if (m_end - m_c < 20) flush();
*m_c++ = x;
return *this;
}
OutputHelper &operator<<(std::string_view s) {
if (m_end - m_c < s.size()) flush();
memcpy(m_c, s.data(), s.size()), m_c += s.size();
return *this;
}
OutputHelper &operator<<(uint64_t x) {
if (m_end - m_c < 20) flush();
#define CASEW(w) \
case TenPow<uint64_t, w - 1>::value... TenPow<uint64_t, w>::value - 1: \
*(uint32_t *)m_c = pre.m_data[x / TenPow<uint64_t, w - 4>::value]; \
m_c += 4, x %= TenPow<uint64_t, w - 4>::value;
switch (x) {
CASEW(19);
CASEW(15);
CASEW(11);
CASEW(7);
case 100 ... 999:
*(uint32_t *)m_c = pre.m_data[x * 10];
m_c += 3;
break;
CASEW(18);
CASEW(14);
CASEW(10);
CASEW(6);
case 10 ... 99:
*(uint32_t *)m_c = pre.m_data[x * 100];
m_c += 2;
break;
CASEW(17);
CASEW(13);
CASEW(9);
CASEW(5);
case 0 ... 9:
*m_c++ = '0' + x;
break;
default:
*(uint32_t *)m_c = pre.m_data[x / TenPow<uint64_t, 16>::value];
m_c += 4;
x %= TenPow<uint64_t, 16>::value;
CASEW(16);
CASEW(12);
CASEW(8);
case 1000 ... 9999:
*(uint32_t *)m_c = pre.m_data[x];
m_c += 4;
break;
}
#undef CASEW
return *this;
}
OutputHelper &operator<<(uint32_t x) {
if (m_end - m_c < 20) flush();
#define CASEW(w) \
case TenPow<uint32_t, w - 1>::value... TenPow<uint32_t, w>::value - 1: \
*(uint32_t *)m_c = pre.m_data[x / TenPow<uint32_t, w - 4>::value]; \
m_c += 4, x %= TenPow<uint32_t, w - 4>::value;
switch (x) {
default:
*(uint32_t *)m_c = pre.m_data[x / TenPow<uint32_t, 6>::value];
m_c += 4;
x %= TenPow<uint32_t, 6>::value;
CASEW(6);
case 10 ... 99:
*(uint32_t *)m_c = pre.m_data[x * 100];
m_c += 2;
break;
CASEW(9);
CASEW(5);
case 0 ... 9:
*m_c++ = '0' + x;
break;
CASEW(8);
case 1000 ... 9999:
*(uint32_t *)m_c = pre.m_data[x];
m_c += 4;
break;
CASEW(7);
case 100 ... 999:
*(uint32_t *)m_c = pre.m_data[x * 10];
m_c += 3;
break;
}
#undef CASEW
return *this;
}
OutputHelper &operator<<(int64_t x) {
if (x >= 0)
return (*this) << uint64_t(x);
else
return (*this) << '-' << uint64_t(-x);
}
OutputHelper &operator<<(int32_t x) {
if (x >= 0)
return (*this) << uint32_t(x);
else
return (*this) << '-' << uint32_t(-x);
}
};
}
}
#endif
namespace SPARSE {
#ifndef __OY_CATTREE__
#define __OY_CATTREE__
namespace OY {
namespace CAT {
using size_type = uint32_t;
template <typename Tp, typename Operation>
struct BaseMonoid {
using value_type = Tp;
static value_type op(const value_type &x, const value_type &y) { return Operation()(x, y); }
};
template <typename Tp, typename Compare>
struct ChoiceByCompare {
Tp operator()(const Tp &x, const Tp &y) const { return Compare()(x, y) ? y : x; }
};
template <typename Tp, Tp (*Fp)(Tp, Tp)>
struct FpTransfer {
Tp operator()(const Tp &x, const Tp &y) const { return Fp(x, y); }
};
template <typename Monoid, size_t MAX_LEVEL = 30>
class Table {
public:
using monoid = Monoid;
using value_type = typename Monoid::value_type;
private:
std::vector<value_type> m_sub[MAX_LEVEL];
size_type m_size, m_depth;
void _update(size_type i) {
auto sub = m_sub[0].data();
for (size_type j = 1, k = 4; j != m_depth; j++, k <<= 1) {
auto cur = m_sub[j].data();
size_type l = i & -(1 << (j + 1));
if (i >> j & 1) {
size_type j = i, end = std::min(l + k, m_size);
cur[j] = (j == l + (k >> 1)) ? sub[j] : Monoid::op(cur[j - 1], sub[j]);
while (++j != end) cur[j] = Monoid::op(cur[j - 1], sub[j]);
} else {
if (m_size <= l + k / 2) continue;
size_type j = i + 1;
cur[j - 1] = (j == l + (k >> 1)) ? sub[j - 1] : Monoid::op(sub[j - 1], cur[j]);
while (--j != l) cur[j - 1] = Monoid::op(sub[j - 1], cur[j]);
}
}
}
public:
Table() = default;
template <typename InitMapping>
Table(size_type length, InitMapping mapping) { resize(length, mapping); }
template <typename Iterator>
Table(Iterator first, Iterator last) { reset(first, last); }
template <typename InitMapping>
void resize(size_type length, InitMapping mapping) {
if (!(m_size = length)) return;
m_depth = m_size == 1 ? 1 : std::bit_width(m_size - 1);
for (size_type i = 0; i != m_depth; i++) m_sub[i].resize(m_size);
auto sub = m_sub[0].data();
for (size_type i = 0; i != m_size; i++) sub[i] = mapping(i);
for (size_type j = 1, k = 4, l; j != m_depth; j++, k <<= 1) {
auto cur = m_sub[j].data();
for (l = 0; l + k <= m_size; l += k) {
size_type i = l + (k >> 1);
cur[i - 1] = sub[i - 1];
while (--i != l) cur[i - 1] = Monoid::op(sub[i - 1], cur[i]);
i = l + (k >> 1);
cur[i] = sub[i];
while (++i != l + k) cur[i] = Monoid::op(cur[i - 1], sub[i]);
}
if (l != m_size && (l + (k >> 1) < m_size)) {
size_type i = l + (k >> 1);
cur[i - 1] = sub[i - 1];
while (--i != l) cur[i - 1] = Monoid::op(sub[i - 1], cur[i]);
i = l + (k >> 1);
cur[i] = sub[i];
while (++i != m_size) cur[i] = Monoid::op(cur[i - 1], sub[i]);
}
}
}
template <typename Iterator>
void reset(Iterator first, Iterator last) {
resize(last - first, [&](size_type i) { return *(first + i); });
}
size_type size() const { return m_size; }
void modify(size_type i, value_type val) { m_sub[0][i] = val, _update(i); }
value_type query(size_type i) const { return m_sub[0][i]; }
value_type query(size_type left, size_type right) const {
if (left == right) return m_sub[0][left];
size_type d = std::bit_width(left ^ right) - 1;
return Monoid::op(m_sub[d][left], m_sub[d][right]);
}
value_type query_all() const { return query(0, m_size - 1); }
template <typename Judger>
size_type max_right(size_type left, Judger &&judge) const {
value_type val = m_sub[0][left];
if (!judge(val)) return left - 1;
if (++left == m_size) return left - 1;
size_type d = std::bit_width(left ^ (m_size - 1));
while (d && left < m_size) {
size_type split = (left & -(1 << (d - 1))) | (1 << (d - 1));
if (m_size <= split)
while (--d && (left >> (d - 1) & 1)) {}
else {
value_type a = Monoid::op(val, m_sub[d - 1][left]);
if (judge(a))
val = a, --d, left = split;
else
while (--d && (left >> (d - 1) & 1)) {}
}
}
if (left < m_size && judge(Monoid::op(val, m_sub[0][left]))) left++;
return std::min(left, m_size) - 1;
}
template <typename Judger>
size_type min_left(size_type right, Judger &&judge) const {
value_type val = m_sub[0][right];
if (!judge(val)) return right + 1;
if (!right--) return right + 1;
size_type d = std::bit_width(right);
while (d) {
value_type a = Monoid::op(m_sub[d - 1][right], val);
if (judge(a))
val = a, --d, right = (right & -(1 << d)) - 1;
else
while (--d && !(right >> (d - 1) & 1)) {}
}
if (!(right & 1) && judge(Monoid::op(m_sub[0][right], val))) right--;
return right + 1;
}
};
template <typename Ostream, typename Monoid, size_t MAX_LEVEL>
Ostream &operator<<(Ostream &out, const Table<Monoid, MAX_LEVEL> &x) {
out << "[";
for (size_type i = 0; i != x.size(); i++) {
if (i) out << ", ";
out << x.query(i);
}
return out << "]";
}
}
template <typename Tp, size_t MAX_LEVEL = 30, typename Operation, typename InitMapping, typename TreeType = CAT::Table<CAT::BaseMonoid<Tp, Operation>, MAX_LEVEL>>
auto make_CatTree(CAT::size_type length, Operation op, InitMapping mapping) -> TreeType { return TreeType(length, mapping); }
template <size_t MAX_LEVEL = 30, typename Iterator, typename Operation, typename Tp = typename std::iterator_traits<Iterator>::value_type, typename TreeType = CAT::Table<CAT::BaseMonoid<Tp, Operation>, MAX_LEVEL>>
auto make_CatTree(Iterator first, Iterator last, Operation op) -> TreeType { return TreeType(first, last); }
template <typename Tp, size_t MAX_LEVEL = 30>
using CatMaxTable = CAT::Table<CAT::BaseMonoid<Tp, CAT::ChoiceByCompare<Tp, std::less<Tp>>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatMinTable = CAT::Table<CAT::BaseMonoid<Tp, CAT::ChoiceByCompare<Tp, std::greater<Tp>>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatGcdTable = CAT::Table<CAT::BaseMonoid<Tp, CAT::FpTransfer<Tp, std::gcd<Tp>>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatLcmTable = CAT::Table<CAT::BaseMonoid<Tp, CAT::FpTransfer<Tp, std::lcm<Tp>>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatBitAndTable = CAT::Table<CAT::BaseMonoid<Tp, std::bit_and<Tp>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatBitOrTable = CAT::Table<CAT::BaseMonoid<Tp, std::bit_or<Tp>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatBitXorTable = CAT::Table<CAT::BaseMonoid<Tp, std::bit_xor<Tp>>, MAX_LEVEL>;
template <typename Tp, size_t MAX_LEVEL = 30>
using CatSumTable = CAT::Table<CAT::BaseMonoid<Tp, std::plus<Tp>>, MAX_LEVEL>;
}
#endif
#ifndef __OY_SQRTTREE__
#define __OY_SQRTTREE__
namespace OY {
namespace SQRT {
using size_type = uint32_t;
using CAT::BaseMonoid;
using CAT::ChoiceByCompare;
using CAT::FpTransfer;
template <size_type BlockSize = 16>
struct StaticController {
void reserve(size_type capacity) {}
static constexpr bool is_first(size_type i) { return i % BlockSize == 0; }
static constexpr size_type block_id(size_type i) { return i / BlockSize; }
static constexpr size_type block_first(size_type i) { return i / BlockSize * BlockSize; }
static constexpr size_type block_size() { return BlockSize; }
static constexpr size_type block_count(size_type length) { return (length + BlockSize - 1) / BlockSize; }
};
template <size_type DefaultDepth = 5>
struct RandomController {
size_type m_mask = (1 << DefaultDepth) - 1, m_depth = DefaultDepth;
void reserve(size_type capacity) { m_depth = (std::bit_width(capacity) - 1) / 2, m_mask = (1 << m_depth) - 1; }
bool is_first(size_type i) const { return !(i & m_mask); }
size_type block_id(size_type i) const { return i >> m_depth; }
size_type block_first(size_type i) const { return i & ~m_mask; }
size_type block_size() const { return m_mask + 1; }
size_type block_count(size_type length) const { return (length + m_mask) >> m_depth; }
};
template <size_type DefaultDepth = 5>
struct NonRandomController {
size_type m_mask = (1 << DefaultDepth) - 1, m_depth = DefaultDepth;
void reserve(size_type capacity) { m_depth = capacity >= 32 ? std::bit_width<size_type>(std::bit_width(capacity / std::bit_width(capacity)) - 1) : (std::bit_width(capacity) - 1) / 2, m_mask = (size_type(1) << m_depth) - 1; }
bool is_first(size_type i) const { return !(i & m_mask); }
size_type block_id(size_type i) const { return i >> m_depth; }
size_type block_first(size_type i) const { return i & ~m_mask; }
size_type block_size() const { return m_mask + 1; }
size_type block_count(size_type length) const { return (length + m_mask) >> m_depth; }
};
template <typename Monoid, typename Controller = RandomController<>, size_t MAX_LEVEL = 30>
class Table {
public:
using monoid = Monoid;
using value_type = typename Monoid::value_type;
using inner_table = CAT::Table<Monoid, MAX_LEVEL>;
private:
inner_table m_table;
std::vector<value_type> m_data, m_prefix, m_suffix;
size_type m_size;
Controller m_ctrl;
template <typename Judger>
size_type _max_right(size_type left, size_type end, Judger &&judge) const {
value_type val = m_data[left];
if (judge(val))
while (++left != end) {
value_type a = Monoid::op(val, m_data[left]);
if (!judge(a)) break;
val = a;
}
return left - 1;
}
template <typename Judger>
size_type _max_right2(size_type left, size_type end, Judger &&judge) const {
size_type low = left, high = end;
while (low != high) {
size_type mid = (low + high) / 2;
if (judge(m_prefix[mid]))
low = mid + 1;
else
high = mid;
}
return low - 1;
}
template <typename Judger>
size_type _min_left(size_type end, size_type right, Judger &&judge) const {
value_type val = m_data[right];
if (judge(val))
while (--right != end) {
value_type a = Monoid::op(m_data[right], val);
if (!judge(a)) break;
val = a;
}
return right + 1;
}
template <typename Judger>
size_type _min_left2(size_type end, size_type right, Judger &&judge) const {
size_type low = end, high = right;
while (low != high) {
size_type mid = (low + high + 1) / 2;
if (judge(m_suffix[mid]))
high = mid - 1;
else
low = mid;
}
return low + 1;
}
void _update(size_type i) {
size_type cur = m_ctrl.block_first(i), nxt = std::min(cur + m_ctrl.block_size(), m_size);
m_prefix[i] = (i == cur) ? m_data[i] : Monoid::op(m_prefix[i - 1], m_data[i]);
for (size_type j = i + 1; j != nxt; j++) m_prefix[j] = Monoid::op(m_prefix[j - 1], m_data[j]);
m_suffix[i] = (i == nxt - 1) ? m_data[i] : Monoid::op(m_data[i], m_suffix[i + 1]);
for (size_type j = i - 1; j != cur - 1; j--) m_suffix[j] = Monoid::op(m_data[j], m_suffix[j + 1]);
m_table.modify(m_ctrl.block_id(i), m_suffix[cur]);
}
public:
Table() = default;
template <typename InitMapping>
Table(size_type length, InitMapping mapping) { resize(length, mapping); }
template <typename Iterator>
Table(Iterator first, Iterator last) { reset(first, last); }
size_type size() const { return m_size; }
template <typename InitMapping>
void resize(size_type length, InitMapping mapping) {
if (!(m_size = length)) return;
m_ctrl.reserve(m_size);
m_data.resize(m_size);
for (size_type i = 0; i != m_size; i++) m_data[i] = mapping(i);
m_prefix = m_suffix = m_data;
for (size_type i = 1; i != m_size; i++)
if (!m_ctrl.is_first(i)) m_prefix[i] = Monoid::op(m_prefix[i - 1], m_prefix[i]);
for (size_type i = m_size - 1; i; i--)
if (!m_ctrl.is_first(i)) m_suffix[i - 1] = Monoid::op(m_suffix[i - 1], m_suffix[i]);
m_table.resize(m_ctrl.block_count(m_size), [&](size_type i) { return m_suffix[i * m_ctrl.block_size()]; });
}
template <typename Iterator>
void reset(Iterator first, Iterator last) {
resize(last - first, [&](size_type i) { return *(first + i); });
}
void modify(size_type i, value_type val) { m_data[i] = val, _update(i); }
value_type query(size_type i) const { return m_data[i]; }
value_type query(size_type left, size_type right) const {
size_type l = m_ctrl.block_id(left), r = m_ctrl.block_id(right);
if (l == r) {
value_type res = m_data[left];
#ifndef __clang__
#pragma GCC unroll 64
#endif
for (size_type i = left + 1; i <= right; i++) res = Monoid::op(res, m_data[i]);
return res;
} else if (l + 1 == r)
return Monoid::op(m_suffix[left], m_prefix[right]);
else
return Monoid::op(Monoid::op(m_suffix[left], m_table.query(l + 1, r - 1)), m_prefix[right]);
}
value_type query_all() const { return m_table.query_all(); }
template <typename Judger>
size_type max_right(size_type left, Judger &&judge) const {
value_type val = m_suffix[left];
if (!judge(val)) return _max_right(left, std::min(m_size, m_ctrl.block_first(left) + m_ctrl.block_size()), judge);
size_type l = m_ctrl.block_id(left);
if (l + 1 == m_table.size()) return m_size - 1;
size_type r = m_table.max_right(l + 1, [&](const value_type &x) { return judge(Monoid::op(val, x)); });
if (r + 1 == m_table.size()) return m_size - 1;
if (r > l) val = Monoid::op(val, m_table.query(l + 1, r));
return _max_right2((r + 1) * m_ctrl.block_size(), std::min(m_size, (r + 2) * m_ctrl.block_size()), [&](const value_type &x) { return judge(Monoid::op(val, x)); });
}
template <typename Judger>
size_type min_left(size_type right, Judger &&judge) const {
value_type val = m_prefix[right];
if (!judge(val)) return _min_left(m_ctrl.block_first(right) - 1, right, judge);
size_type r = m_ctrl.block_id(right);
if (!r) return 0;
size_type l = m_table.min_left(r - 1, [&](const value_type &x) { return judge(Monoid::op(x, val)); });
if (!l) return 0;
if (l < r) val = Monoid::op(m_table.query(l, r - 1), val);
return _min_left2(((l - 1) * m_ctrl.block_size()) - 1, (l * m_ctrl.block_size()) - 1, [&](const value_type &x) { return judge(Monoid::op(x, val)); });
}
};
template <typename Ostream, typename Node, typename Controller, size_t MAX_LEVEL>
Ostream &operator<<(Ostream &out, const Table<Node, Controller, MAX_LEVEL> &x) {
out << "[";
for (size_type i = 0; i != x.size(); i++) {
if (i) out << ", ";
out << x.query(i);
}
return out << "]";
}
}
template <typename Tp, typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30, typename Operation, typename InitMapping, typename TreeType = SQRT::Table<SQRT::BaseMonoid<Tp, Operation>, Controller, MAX_LEVEL>>
auto make_SqrtTree(SQRT::size_type length, Operation op, InitMapping mapping) -> TreeType { return TreeType(length, mapping); }
template <typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30, typename Iterator, typename Operation, typename Tp = typename std::iterator_traits<Iterator>::value_type, typename TreeType = SQRT::Table<SQRT::BaseMonoid<Tp, Operation>, Controller, MAX_LEVEL>>
auto make_SqrtTree(Iterator first, Iterator last, Operation op) -> TreeType { return TreeType(first, last); }
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtMaxTable = SQRT::Table<SQRT::BaseMonoid<Tp, SQRT::ChoiceByCompare<Tp, std::less<Tp>>>, Controller, MAX_LEVEL>;
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtMinTable = SQRT::Table<SQRT::BaseMonoid<Tp, SQRT::ChoiceByCompare<Tp, std::greater<Tp>>>, Controller, MAX_LEVEL>;
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtGcdTable = SQRT::Table<SQRT::BaseMonoid<Tp, SQRT::FpTransfer<Tp, std::gcd<Tp>>>, Controller, MAX_LEVEL>;
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtLcmTable = SQRT::Table<SQRT::BaseMonoid<Tp, SQRT::FpTransfer<Tp, std::lcm<Tp>>>, Controller, MAX_LEVEL>;
template <typename Tp, typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtBitAndTable = SQRT::Table<SQRT::BaseMonoid<Tp, std::bit_and<Tp>>, Controller, MAX_LEVEL>;
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtBitOrTable = SQRT::Table<SQRT::BaseMonoid<Tp, std::bit_or<Tp>>, Controller, MAX_LEVEL>;
template <typename Tp, typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtBitXorTable = SQRT::Table<SQRT::BaseMonoid<Tp, std::bit_xor<Tp>>, Controller, MAX_LEVEL>;
template <typename Tp,typename Controller = SQRT::RandomController<>, size_t MAX_LEVEL = 30>
using SqrtSumTable = SQRT::Table<SQRT::BaseMonoid<Tp, std::plus<Tp>>, Controller, MAX_LEVEL>;
}
#endif
}
namespace SOLVE_2D {
#ifndef __OY_WAVELET__
#define __OY_WAVELET__
namespace OY {
namespace WaveLet {
using size_type = uint32_t;
using mask_type = uint64_t;
struct Ignore {};
static constexpr size_type MASK_SIZE = sizeof(mask_type) << 3, MASK_WIDTH = MASK_SIZE / 32 + 4;
struct BitRank {
std::vector<mask_type> m_bits;
std::vector<size_type> m_sum;
void resize(size_type length) { m_bits.assign((length >> MASK_WIDTH) + 1, 0), m_sum.resize(m_bits.size()); }
void set(size_type i, mask_type val) { m_bits[i >> MASK_WIDTH] |= val << (i & (MASK_SIZE - 1)); }
void prepare() {
for (size_type i = 1; i != m_bits.size(); i++) m_sum[i] = m_sum[i - 1] + std::popcount(m_bits[i - 1]);
}
size_type rank1(size_type i) const { return m_sum[i >> MASK_WIDTH] + std::popcount(m_bits[i >> MASK_WIDTH] & ((mask_type(1) << (i & (MASK_SIZE - 1))) - 1)); }
size_type rank1(size_type l, size_type r) const { return rank1(r) - rank1(l); }
size_type rank0(size_type i) const { return i - rank1(i); }
size_type rank0(size_type l, size_type r) const { return rank0(r) - rank0(l); }
};
struct VoidTable {
template <typename Iterator>
void reset(Iterator first, Iterator last) {}
template <typename InitMapping>
void resize(size_type length, InitMapping) {}
size_type query(size_type left, size_type right) const { return right - left + 1; }
};
template <typename Tp, typename SumTable = VoidTable>
struct Table {
size_type m_size, m_alpha;
std::vector<BitRank> m_ranks;
std::vector<size_type> m_pos;
std::vector<SumTable> m_sumer;
Table() = default;
template <typename InitMapping, typename TableMapping = Ignore>
Table(size_type length, InitMapping mapping, size_type alpha = 0, TableMapping table_mapping = TableMapping()) { resize(length, mapping, alpha, table_mapping); }
template <typename Iterator, typename TableMapping = Ignore>
Table(Iterator first, Iterator last, size_type alpha = 0, TableMapping table_mapping = TableMapping()) { reset(first, last, alpha, table_mapping); }
template <typename InitMapping, typename TableMapping = Ignore>
void resize(size_type length, InitMapping mapping, size_type alpha = 0, TableMapping table_mapping = TableMapping()) {
static_assert(std::is_unsigned<Tp>::value, "Tp Must Be Unsigned Type");
if (!(m_size = length)) return;
std::vector<Tp> numbers(m_size);
for (size_type i = 0; i != m_size; i++) numbers[i] = mapping(i);
m_alpha = alpha ? alpha : std::max<uint32_t>(1, std::bit_width(*std::max_element(numbers.begin(), numbers.end())));
m_ranks.resize(m_alpha), m_pos.resize(m_alpha);
m_sumer.resize(m_alpha);
for (size_type d = m_alpha - 1; ~d; d--) {
m_ranks[d].resize(m_size);
for (size_type i = 0; i != m_size; i++) m_ranks[d].set(i, numbers[i] >> d & 1);
m_ranks[d].prepare();
m_pos[d] = std::stable_partition(numbers.begin(), numbers.end(), [&](size_type val) { return !(val >> d & 1); }) - numbers.begin();
if constexpr (std::is_same<TableMapping, Ignore>::value)
m_sumer[d].reset(numbers.begin(), numbers.end());
else
m_sumer[d].resize(m_size, [&](size_type i) { return table_mapping(numbers[i]); });
}
}
template <typename Iterator, typename TableMapping = Ignore>
void reset(Iterator first, Iterator last, size_type alpha = 0, TableMapping table_mapping = TableMapping()) {
resize(
last - first, [&](size_type i) { return *(first + i); }, alpha, table_mapping);
}
size_type count(size_type left, size_type right, Tp val) const {
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right);
if (!(val >> d & 1))
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr;
}
return right - left;
}
size_type count(size_type left, size_type right, Tp minimum, Tp maximum) const {
size_type l1 = left, r1 = right + 1, l2 = left, r2 = right + 1, res = 0;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl1 = m_ranks[d].rank0(l1), zr1 = m_ranks[d].rank0(r1), zl2 = m_ranks[d].rank0(l2), zr2 = m_ranks[d].rank0(r2);
if (!(minimum >> d & 1))
l1 = zl1, r1 = zr1;
else
res -= zr1 - zl1, l1 += m_pos[d] - zl1, r1 += m_pos[d] - zr1;
if (!(maximum >> d & 1))
l2 = zl2, r2 = zr2;
else
res += zr2 - zl2, l2 += m_pos[d] - zl2, r2 += m_pos[d] - zr2;
}
return r2 - l2 + res;
}
size_type rank(size_type left, size_type right, Tp val) const {
size_type ans = 0;
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right);
if (!(val >> d & 1))
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr, ans += zr - zl;
}
return ans;
}
Tp minimum(size_type left, size_type right) const {
Tp ans = 0;
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right);
if (zl != zr)
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr, ans |= Tp(1) << d;
}
return ans;
}
Tp maximum(size_type left, size_type right) const {
Tp ans = 0;
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right);
if (zr - zl == right - left)
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr, ans |= Tp(1) << d;
}
return ans;
}
Tp quantile(size_type left, size_type right, size_type k) const {
Tp ans = 0;
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right), z = zr - zl;
if (k < z)
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr, k -= z, ans |= Tp(1) << d;
}
return ans;
}
Tp max_bitxor(size_type left, size_type right, Tp val) const {
Tp ans = 0;
right++;
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right), z = zr - zl;
if (val >> d & 1)
if (z)
left = zl, right = zr, ans |= Tp(1) << d;
else
left += m_pos[d] - zl, right += m_pos[d] - zr;
else if (right - left - z)
left += m_pos[d] - zl, right += m_pos[d] - zr, ans |= Tp(1) << d;
else
left = zl, right = zr;
}
return ans;
}
template <typename Callback>
void do_for_rank_range(size_type left, size_type right, size_type rk1, size_type rk2, Callback &&call) const {
right++;
auto handle = [&](size_type l1, size_type r1, size_type l2, size_type r2, size_type k1, size_type k2, size_type d) {
for (; ~d; d--) {
size_type one_l = m_ranks[d].rank1(l1), one_r = m_ranks[d].rank1(r1), one = one_r - one_l, zl = m_ranks[d].rank0(l2), zr = m_ranks[d].rank0(r2), z = zr - zl;
if (k1 < one)
l1 = m_pos[d] + one_l, r1 = m_pos[d] + one_r;
else {
l1 -= one_l, r1 -= one_r, k1 -= one;
if (one) call(m_sumer[d].query(m_pos[d] + one_l, m_pos[d] + one_r - 1));
}
if (k2 < z)
l2 = zl, r2 = zr;
else {
l2 += m_pos[d] - zl, r2 += m_pos[d] - zr, k2 -= z;
if (z) call(m_sumer[d].query(zl, zr - 1));
}
}
if (k1) call(m_sumer[0].query(l1, l1 + k1 - 1));
if (k2) call(m_sumer[0].query(r2 - k2, r2 - 1));
};
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right), z = zr - zl;
if (rk2 < z)
left = zl, right = zr;
else if (rk1 >= z)
left += m_pos[d] - zl, right += m_pos[d] - zr, rk1 -= z, rk2 -= z;
else
return handle(zl, zr, left + m_pos[d] - zl, right + m_pos[d] - zr, z - rk1, rk2 - z + 1, d - 1);
}
if (left != right) call(m_sumer[0].query(left + rk1, left + rk2));
}
template <typename Callback>
void do_for_value_range(size_type left, size_type right, Tp floor, Tp ceil, Callback &&call) const {
right++;
auto handle = [&](size_type l1, size_type r1, size_type l2, size_type r2, size_type d) {
for (; ~d; d--) {
size_type one_l = m_ranks[d].rank1(l1), one_r = m_ranks[d].rank1(r1), one = one_r - one_l, zl = m_ranks[d].rank0(l2), zr = m_ranks[d].rank0(r2), z = zr - zl;
if (floor >> d & 1)
l1 = m_pos[d] + one_l, r1 = m_pos[d] + one_r;
else {
l1 -= one_l, r1 -= one_r;
if (one) call(m_sumer[d].query(m_pos[d] + one_l, m_pos[d] + one_r - 1));
}
if (!(ceil >> d & 1))
l2 = zl, r2 = zr;
else {
l2 += m_pos[d] - zl, r2 += m_pos[d] - zr;
if (z) call(m_sumer[d].query(zl, zr - 1));
}
}
if (l1 != r1) call(m_sumer[0].query(l1, r1 - 1));
if (l2 != r2) call(m_sumer[0].query(l2, r2 - 1));
};
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(left), zr = m_ranks[d].rank0(right), z = zr - zl;
if ((floor >> d & 1) == (ceil >> d & 1))
if (!(floor >> d & 1))
left = zl, right = zr;
else
left += m_pos[d] - zl, right += m_pos[d] - zr;
else
return handle(zl, zr, left + m_pos[d] - zl, right + m_pos[d] - zr, d - 1);
}
if (left != right) call(m_sumer[0].query(left, right - 1));
}
template <typename Callback>
void do_in_table(size_type pos, Callback &&call) {
for (size_type d = m_alpha - 1; ~d; d--) {
size_type zl = m_ranks[d].rank0(pos), zr = m_ranks[d].rank0(pos + 1);
call(m_sumer[d], pos = zl == zr ? pos + m_pos[d] - zl : zl);
}
}
};
template <typename Tp, typename SumTable = VoidTable>
struct Tree {
Table<size_type, SumTable> m_table;
std::vector<Tp> m_discretizer;
size_type m_size;
size_type _find(const Tp &val) const { return std::lower_bound(m_discretizer.begin(), m_discretizer.end(), val) - m_discretizer.begin(); }
size_type _upper_find(const Tp &val) const { return std::upper_bound(m_discretizer.begin(), m_discretizer.end(), val) - m_discretizer.begin(); }
Tree() = default;
template <typename InitMapping, typename TableMapping = Ignore>
Tree(size_type length, InitMapping mapping, TableMapping table_mapping = TableMapping()) { resize(length, mapping, table_mapping); }
template <typename Iterator, typename TableMapping = Ignore>
Tree(Iterator first, Iterator last, TableMapping table_mapping = TableMapping()) { reset(first, last, table_mapping); }
template <typename InitMapping, typename TableMapping = Ignore>
void resize(size_type length, InitMapping mapping, TableMapping table_mapping = TableMapping()) {
if (!(m_size = length)) return;
std::vector<Tp> items(m_size);
for (size_type i = 0; i != m_size; i++) items[i] = mapping(i);
m_discretizer = items;
std::sort(m_discretizer.begin(), m_discretizer.end());
m_discretizer.erase(std::unique(m_discretizer.begin(), m_discretizer.end()), m_discretizer.end());
if constexpr (std::is_same<TableMapping, Ignore>::value)
m_table.resize(
m_size, [&](size_type i) { return _find(items[i]); }, std::bit_width(m_discretizer.size()), [&](size_type val) { return m_discretizer[val]; });
else
m_table.resize(
m_size, [&](size_type i) { return _find(items[i]); }, std::bit_width(m_discretizer.size()), [&](size_type val) { return table_mapping(m_discretizer[val]); });
}
template <typename Iterator, typename TableMapping>
void reset(Iterator first, Iterator last, TableMapping table_mapping = TableMapping()) {
resize(
last - first, [&](size_type i) { return *(first + i); }, table_mapping);
}
size_type count(size_type left, size_type right, const Tp &val) const {
size_type find = _find(val);
return find < m_discretizer.size() && m_discretizer[find] == val ? m_table.count(left, right, find) : 0;
}
size_type count(size_type left, size_type right, const Tp &minimum, const Tp &maximum) const {
size_type find1 = _find(minimum);
if (find1 == m_discretizer.size()) return 0;
size_type find2 = _find(maximum);
return find2 < m_discretizer.size() && m_discretizer[find2] == maximum ? m_table.count(left, right, find1, find2) : m_table.count(left, right, find1, find2 - 1);
}
size_type rank(size_type left, size_type right, const Tp &val) const { return m_table.rank(left, right, _find(val)); }
Tp minimum(size_type left, size_type right) const { return m_discretizer[m_table.minimum(left, right)]; }
Tp maximum(size_type left, size_type right) const { return m_discretizer[m_table.maximum(left, right)]; }
Tp quantile(size_type left, size_type right, size_type k) const { return m_discretizer[m_table.quantile(left, right, k)]; }
template <typename Callback>
void do_for_rank_range(size_type left, size_type right, size_type rk1, size_type rk2, Callback &&call) const { m_table.do_for_rank_range(left, right, rk1, rk2, call); }
template <typename Callback>
void do_for_value_range(size_type left, size_type right, const Tp &floor, const Tp &ceil, Callback &&call) const { m_table.do_for_value_range(left, right, _find(floor), _upper_find(ceil) - 1, call); }
};
}
}
#endif
#ifndef __OY_POINTADDRECTSUMCOUNTER2D__
#define __OY_POINTADDRECTSUMCOUNTER2D__
namespace OY {
namespace PARSC2D {
using size_type = uint32_t;
template <typename SizeType, typename WeightType, bool HasModify>
struct Point {
SizeType m_x, m_y;
WeightType m_w;
};
template <typename SizeType, typename WeightType>
struct Point<SizeType, WeightType, true> {
SizeType m_x, m_y;
size_type m_index;
WeightType m_w;
};
template <typename SizeType>
struct Point<SizeType, bool, false> {
SizeType m_x, m_y;
};
template <typename SizeType>
struct Point<SizeType, bool, true> {
SizeType m_x, m_y;
size_type m_index;
};
template <typename Tp>
struct AdjTable {
std::vector<Tp> m_sum;
template <typename InitMapping>
void resize(size_type length, InitMapping mapping) {
m_sum.resize(length + 1);
for (size_type i = 0; i != length; i++) m_sum[i + 1] = m_sum[i] + mapping(i);
}
Tp query(size_type left, size_type right) const { return m_sum[right + 1] - m_sum[left]; }
};
template <typename Tp>
struct SimpleBIT {
std::vector<Tp> m_sum;
static size_type _lowbit(size_type x) { return x & -x; }
template <typename InitMapping>
void resize(size_type length, InitMapping mapping) {
m_sum.resize(length);
for (size_type i = 0; i != length; i++) m_sum[i] = mapping(i);
for (size_type i = 0; i != length; i++) {
size_type j = i + _lowbit(i + 1);
if (j < length) m_sum[j] += m_sum[i];
}
}
void add(size_type i, size_type inc) {
while (i < m_sum.size()) m_sum[i] += inc, i += _lowbit(i + 1);
}
Tp presum(size_type i) const {
Tp res{};
for (size_type j = i; ~j; j -= _lowbit(j + 1)) res += m_sum[j];
return res;
}
Tp query(size_type left, size_type right) const { return presum(right) - presum(left - 1); }
};
template <typename SizeType, typename WeightType = bool, typename SumType = typename std::conditional<std::is_same<WeightType, bool>::value, size_type, WeightType>::type, bool HasModify = false>
struct Table {
static constexpr bool is_bool = std::is_same<WeightType, bool>::value;
using point = Point<SizeType, WeightType, HasModify>;
using inner_table = typename std::conditional<HasModify, SimpleBIT<SumType>, AdjTable<SumType>>::type;
using wavelet = WaveLet::Table<size_type, inner_table>;
std::vector<point> m_points;
std::vector<SizeType> m_sorted_xs, m_ys;
std::vector<size_type> m_point_pos;
wavelet m_table;
Table() = default;
Table(size_type point_cnt) { m_points.reserve(point_cnt); }
void add_point(SizeType x, SizeType y, WeightType w = 1) {
if constexpr (is_bool)
if constexpr (HasModify)
m_points.push_back({x, y, size_type(m_points.size())});
else
m_points.push_back({x, y});
else if constexpr (HasModify)
m_points.push_back({x, y, size_type(m_points.size()), w});
else
m_points.push_back({x, y, w});
}
void prepare() {
std::sort(m_points.begin(), m_points.end(), [](const point &x, const point &y) { return x.m_y < y.m_y; });
m_ys.reserve(m_points.size());
std::vector<WeightType> wtable;
if constexpr (!is_bool) wtable.reserve(m_points.size());
for (auto &p : m_points) {
m_ys.push_back(p.m_y), p.m_y = m_ys.size() - 1;
if constexpr (!is_bool) wtable.push_back(p.m_w);
}
std::sort(m_points.begin(), m_points.end(), [](const point &x, const point &y) { return x.m_x < y.m_x; });
auto mapping = [&](size_type i) { return m_points[i].m_y; };
auto table_mapping = [&](size_type y) -> SumType {
if constexpr (is_bool)
return 1;
else
return wtable[y];
};
m_table.resize(m_points.size(), mapping, std::bit_width(m_points.size()), table_mapping);
m_sorted_xs.reserve(m_points.size());
for (auto &p : m_points) m_sorted_xs.push_back(p.m_x);
if constexpr (HasModify) {
m_point_pos.resize(m_points.size());
for (size_type i = 0; i != m_points.size(); i++) m_point_pos[m_points[i].m_index] = i;
}
}
SumType query(SizeType x_min, SizeType x_max, SizeType y_min, SizeType y_max) const {
auto y1 = std::lower_bound(m_ys.begin(), m_ys.end(), y_min) - m_ys.begin(), y2 = std::upper_bound(m_ys.begin(), m_ys.end(), y_max) - m_ys.begin() - 1;
SumType res{};
if (y1 != y2 + 1) m_table.do_for_value_range(std::lower_bound(m_sorted_xs.begin(), m_sorted_xs.end(), x_min) - m_sorted_xs.begin(), std::upper_bound(m_sorted_xs.begin(), m_sorted_xs.end(), x_max) - m_sorted_xs.begin() - 1, y1, y2, [&](SumType val) { res += val; });
return res;
}
void add_point_value(size_type point_id, WeightType w) {
static_assert(HasModify, "HasModify Must Be True");
m_table.do_in_table(m_point_pos[point_id], [w](inner_table &tr, size_type pos) { tr.add(pos, w); });
}
};
};
}
#endif
}
// faster implementation
// source: https://judge.yosupo.jp/submission/42086
void SA_IS(const int *s, int *SA, int n, int K) {
// s 为字符串数组[0..n-1] 必须保证 s[n-1]=0 且为最小值
// SA 为存储后缀数组[0..n-1]
// n 为字符串长度
// K 为值域
bool *t = new bool[n]; // 类型数组
int *bkt = new int[K]; // 桶
int *bkt_l = new int[K];
int *bkt_r = new int[K];
int n1 = 0; // LMS-后缀的数量
int *p1; //按出现顺序存储所有 LMS-后缀的索引
#define is_S_type(x) (t[x])
#define is_L_type(x) (!t[x])
#define is_LMS_type(x) (is_S_type(x) && x != 0 && is_L_type(x - 1))
// 预处理每一个后缀的类型
t[n - 1] = true; // 0 为 S-型后缀且为 LMS-型后缀
for (int i = n - 2; i >= 0; --i) {
t[i] = (s[i] < s[i + 1] || (is_S_type(i + 1) && s[i] == s[i + 1]));
n1 += is_LMS_type(i + 1); // s[0] 必然不是 LMS-型后缀,不会影响
}
// 预处理桶的边界
for (int i = 0; i != K; ++i) bkt[i] = 0;
for (int i = 0; i != n; ++i) ++bkt[s[i]];
for (int i = 0, sum = 0; i != K; ++i) sum += bkt[i], bkt_r[i] = sum, bkt_l[i] = sum - bkt[i];
#define indecud_sort() \
do { \
for (int i = 0; i != K; ++i) bkt[i] = bkt_l[i]; \
for (int i = 0, j; i != n; ++i) \
if ((j = SA[i] - 1) >= 0 && is_L_type(j)) SA[bkt[s[j]]++] = j; \
for (int i = 0; i != K; ++i) bkt[i] = bkt_r[i]; \
for (int i = n - 1, j; i >= 0; --i) \
if ((j = SA[i] - 1) >= 0 && is_S_type(j)) SA[--bkt[s[j]]] = j; \
} while (0)
// 将所有 LMS-后缀放入 SA 对应桶的末尾并诱导排序
p1 = new int[n1];
for (int i = 0, j = 0; i != n; ++i) {
SA[i] = -1;
if (is_LMS_type(i)) p1[j++] = i;
}
for (int i = 0; i != K; ++i) bkt[i] = bkt_r[i];
for (int i = n1 - 1; i >= 0; --i) SA[--bkt[s[p1[i]]]] = p1[i];
indecud_sort();
int *s1 = new int[n1]; // 新的字符串
int *SA1 = new int[n1]; // 存储新的字符串排的后缀数组
for (int i = 0, j = 0; i != n; ++i)
if (is_LMS_type(SA[i])) SA1[j++] = SA[i]; // 存储 LMS-子串的相对顺序
int name = 0;
// 对所有 LMS-子串命名
for (int i = 0, prev = -1; i != n1; ++i) {
int pos = SA1[i];
for (int j = 0;; ++j) // 无需设置范围,因为 s[n-1]=0 为最小值且不会出现在其余位置
if (prev == -1 || s[pos + j] != s[prev + j] || is_S_type(pos + j) != is_S_type(prev + j)) {
prev = pos, ++name;
break;
} else if (j != 0 && (is_LMS_type(pos + j) || is_LMS_type(prev + j))) // 到末尾了停止比较
break;
SA[pos] = name - 1; // 利用 SA 暂时存储新字符串的 name
}
for (int i = 0; i != n1; ++i) s1[i] = SA[p1[i]];
if (name != n1)
SA_IS(s1, SA1, n1, name);
else
for (int i = 0; i != n1; ++i) SA1[s1[i]] = i;
for (int i = 0; i != K; ++i) bkt[i] = bkt_r[i];
for (int i = 0; i != n; ++i) SA[i] = -1;
for (int i = n1 - 1; i >= 0; --i) SA[--bkt[s[p1[SA1[i]]]]] = p1[SA1[i]];
indecud_sort();
delete[] SA1;
delete[] s1;
delete[] p1;
delete[] bkt_r;
delete[] bkt_l;
delete[] bkt;
delete[] t;
#undef is_S_type
#undef is_L_type
#undef is_LMS_type
#undef indecud_sort
}
const ll INF = 2e18;
const int INFi = 1e9;
const int N = 2e5 + 50;
const int LG = 20;
std::vector<int> get_sa(const std::string &s) {
int len = s.size();
std::vector<int> SA(len + 1), s_cpy(len + 1);
for (int i = 0; i != len; ++i) s_cpy[i] = s[i];
s_cpy.back() = 0;
SA_IS(s_cpy.data(), SA.data(), len + 1, 128);
return std::vector<int>(SA.begin() + 1, SA.end());
}
auto min_merge = [](int x, int y) {
return min(x, y);
};
struct suffix_array {
std::vector<int> order, suffix_position, lcp;
string s;
SPARSE::OY::SqrtMinTable<uint32_t, SPARSE::OY::SQRT::NonRandomController<4>, 16> sp;
suffix_array() {
}
void build(std::string str) {
order.clear();
suffix_position.clear();
lcp.clear();
s.clear();
s = str;
int n = str.size() + 1;
order = get_sa(str);
order.insert(order.begin(), n - 1);
suffix_position.resize(n);
for (int i = 0; i < n; i++) {
suffix_position[order[i]] = i;
}
lcp.resize(n);
int current_lcp = 0;
for (int suffix = 0; suffix < n - 1; suffix++, current_lcp = current_lcp == 0 ? 0 : current_lcp - 1) {
int previous_suffix = order[suffix_position[suffix] - 1];
while (str[suffix + current_lcp] == str[previous_suffix + current_lcp])
current_lcp++;
lcp[suffix_position[suffix]] = current_lcp;
}
sp = SPARSE::OY::SqrtMinTable<uint32_t, SPARSE::OY::SQRT::NonRandomController<4>, 16>(all(lcp));
}
int LCP(int l, int r) {
if (l == r) return (int) suffix_position.size() - 1 - l;
l = suffix_position[l];
r = suffix_position[r];
if (l > r) swap(l, r);
return sp.query(l + 1, r);
}
char Get(int pos) {
return s[pos];
}
} S;
struct Element {
vector<pair<uint32_t, uint32_t>> a;
uint32_t idx;
int priority;
ll length;
void read() {
uint32_t k;
cin >> k;
a.resize(k);
length = 0;
for (auto &[l, r]: a) {
cin >> l >> r;
l--;
length += r - l;
}
}
};
pair<bool, ll> Comp(const Element &a, const Element &b) {
if (a.a == b.a) return make_pair(a.priority < b.priority, a.length);
ll total = 0;
int i = 0;
int used_i = 0;
int j = 0;
int used_j = 0;
while (true) {
if (j == b.a.size() && i == a.a.size()) return make_pair(a.priority < b.priority, total);
if (j == b.a.size()) return make_pair(b.priority > 0 ? true : false, total);
if (i == a.a.size()) return make_pair(a.priority > 0 ? false : true, total);
int mx_i = a.a[i].second - a.a[i].first - used_i;
int mx_j = b.a[j].second - b.a[j].first - used_j;
int mx = min(mx_i, mx_j);
int len = S.LCP(a.a[i].first + used_i, b.a[j].first + used_j);
ckmin(len, mx);
used_i += len;
used_j += len;
total += len;
if (len < mx) return make_pair(S.Get(a.a[i].first + used_i) < S.Get(b.a[j].first + used_j), total);
if (mx_i == len) {
i++;
used_i = 0;
}
if (mx_j == len) {
j++;
used_j = 0;
}
}
return {false, 0};
}
bool operator<(const Element &a, const Element &b) {
return Comp(a, b).first;
}
void solve() {
uint32_t n, q;
cin >> n >> q;
string s;
cin >> s;
vector<Element> elems;
vector<int> ban;
auto Add = [&](Element e, int ww) {
e.idx = elems.size();
elems.push_back(e);
ban.push_back(ww);
return e.idx;
};
vector<ar<uint32_t, 5>> qs(q, {0, 0, 0, 0, 0});
for (auto &[tp, l1, r1, l2, r2]: qs) {
char t;
cin >> t;
if (t == '+') {
Element e;
e.read();
e.priority = -1;
tp = 1;
l1 = Add(e, -1);
} else if (t == '-') {
tp = q - 1;
int pos;
cin >> pos;
pos--;
l1 = qs[pos][1];
} else {
tp = 0;
Element e1, e2;
e1.read();
e2.read();
// e1.priority = -2;
// l1 = Add(e1, 1);
e1.priority = 2;
r1 = Add(e1, 1);
// e2.priority = -2;
// l2 = Add(e2, 0);
e2.priority = 2;
r2 = Add(e2, 0);
}
}
vector<ar<int, 2>> pos(elems.size()), pos2(elems.size());
rep(rot, 2) {
S.build(s);
vector<Element> els;
rep(i, elems.size()) if (ban[i] != rot) {
els.push_back(elems[i]);
}
sort(all(els));
vector<pair<ll, int>> stk;
rep(i, els.size()) {
if (i) {
ll val = Comp(els[i - 1], els[i]).second;
int j = i - 1;
while (!stk.empty() && stk.back().first >= val) {
j = stk.back().second;
stk.pop_back();
}
stk.emplace_back(val, j);
}
pos[els[i].idx][rot] = i;
if (!stk.empty() && stk.back().first == els[i].length) {
pos2[els[i].idx][rot] = stk.back().second;
} else {
pos2[els[i].idx][rot] = i;
}
}
reverse(all(s));
for (auto &e: elems) {
for (auto &[l, r]: e.a) {
r--;
swap(l, r);
l = n - 1 - l;
r = n - 1 - r;
r++;
}
reverse(all(e.a));
}
}
SOLVE_2D::OY::PARSC2D::Table<uint32_t, uint32_t, uint64_t, true> sol(0);
for (auto &[tp, l1, r1, l2, r2]: qs) {
if (tp == 1) {
int i = l1;
l1 = r1 = pos[i][0];
l2 = r2 = pos[i][1];
// cerr << "+ " << l1 << ' ' << l2 << endl;
sol.add_point(l1, l2, 0);
// rect1.update(l1, l2, 1);
} else if (tp == q-1) {
int i = l1;
l1 = r1 = pos[i][0];
l2 = r2 = pos[i][1];
// cerr << "- " << l1 << ' ' << l2 << endl;
sol.add_point(l1, l2, 0);
// rect2.update(l1, l2, 1);
} else {
l1 = pos2[r1][0];
r1 = pos[r1][0];
l2 = pos2[r2][1];
r2 = pos[r2][1];
// cerr << "? " << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << endl;
// rect1.query(l1, r1, l2, r2);
// rect2.query(l1, r1, l2, r2);
}
}
sol.prepare();
int id = 0;
for (auto &[tp, l1, r1, l2, r2]: qs) {
if (tp == 1 || tp == q-1) {
sol.add_point_value(id++, tp);
} else {
cout << sol.query(l1, r1, l2, r2) % q << '\n';
}
}
}
signed main() {
int t = 1;
// cin >> t;
rep(i, t) {
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3708kb
input:
8 7 abcaabbc + 3 1 3 2 4 3 8 + 2 1 4 1 8 + 1 2 4 ? 1 5 6 1 7 8 - 3 + 1 2 5 ? 1 2 3 1 5 5
output:
2 1
result:
ok 2 lines
Test #2:
score: 0
Accepted
time: 2ms
memory: 4304kb
input:
5 2000 bbaab + 1 3 5 + 2 5 5 3 5 - 2 ? 1 1 3 3 3 3 4 5 2 5 - 1 ? 3 1 1 2 4 1 5 1 3 4 ? 1 1 2 2 2 4 4 4 ? 1 1 5 1 5 5 + 3 1 2 1 5 1 4 ? 2 1 5 1 3 2 1 2 5 5 ? 1 3 4 1 4 5 - 9 ? 1 1 4 1 2 3 + 2 1 5 1 2 + 1 1 4 - 15 - 14 ? 2 2 5 2 5 1 3 4 + 1 2 3 - 19 + 3 1 4 1 5 4 5 - 21 + 1 2 5 ? 3 1 5 5 5 1 5 1 3 5 ?...
output:
0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 2 0 3 1 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 3 1 0 1 0 2 0 0 0 3 0 1 0 0 2 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 3 2 3 0 0 0 0 0 2 0 0 2 0 0 0 2 3 ...
result:
ok 702 lines
Test #3:
score: 0
Accepted
time: 2ms
memory: 4252kb
input:
5 2000 ababa + 1 4 4 + 1 2 2 ? 1 1 2 2 3 3 3 3 ? 2 3 3 1 2 1 3 4 + 2 3 4 2 2 + 1 3 3 + 1 2 2 + 1 1 2 - 7 - 1 - 2 ? 2 4 4 3 3 2 2 2 4 4 - 5 + 1 1 1 - 6 ? 1 3 4 2 1 2 4 5 + 1 4 5 - 17 ? 2 1 1 1 2 2 1 1 1 2 - 8 + 2 3 4 2 3 + 1 4 5 + 1 2 3 + 1 3 4 - 21 + 1 3 3 ? 1 1 2 1 4 4 ? 2 1 1 4 5 1 5 5 - 24 - 22 ?...
output:
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 2 0 3 1 0 1 0 0 2 0 0 2 0 2 0 3 3 2 4 0 0 0 0 0 0 4 0 0 4 2 1 1 0 0 1 3 2 0 0 0 2 2 0 2 0 0 0 0 0 1 0 3 1 1 0 2 9 0 1 1 1 0 5 8 1 1 1 0 0 5 4 4 4 6 6 0 6 6 1 5 0 3 5 1 0 0 1 8 0 5 0 5 0 3 0 0 0 1 0 1 1 1 1 1 0 0 0 1 5 2 0 2 6 5 1 4 0 0 7 0 2 6 1 5 0 5 0 9 0 0 0 0 1 0 0 ...
result:
ok 647 lines
Test #4:
score: 0
Accepted
time: 2ms
memory: 4228kb
input:
5 2000 bbaba + 1 3 3 - 1 + 2 2 2 1 1 - 3 + 1 4 4 ? 1 3 3 1 2 2 + 2 2 2 1 1 - 5 ? 2 4 4 1 1 2 3 3 3 3 - 7 + 1 5 5 + 2 2 2 2 2 + 1 5 5 - 11 + 2 2 2 1 1 ? 1 3 3 1 2 2 + 1 1 1 + 1 2 2 + 1 3 3 - 17 - 19 + 1 1 1 + 1 3 3 ? 1 3 3 1 3 3 + 1 5 5 ? 1 4 4 1 4 4 - 22 + 1 5 5 + 1 1 1 ? 2 5 5 3 3 1 1 1 ? 1 5 5 1 1...
output:
0 0 0 2 4 0 0 2 5 0 4 0 1 8 0 0 1 6 0 4 7 0 2 0 4 0 0 0 6 1 1 0 0 6 0 9 1 7 0 1 1 0 0 1 7 1 0 1 2 9 0 1 2 2 0 0 2 7 0 4 2 8 2 8 0 1 0 2 0 9 10 1 1 2 1 1 0 0 10 0 0 0 6 0 0 2 4 0 5 4 5 5 5 0 4 0 3 2 2 5 5 5 5 0 0 0 4 0 3 5 5 6 9 6 6 4 6 0 4 6 0 4 4 2 2 12 0 5 6 6 6 13 0 13 2 1 0 1 10 10 5 8 1 8 8 1 1...
result:
ok 672 lines
Test #5:
score: 0
Accepted
time: 196ms
memory: 30444kb
input:
5 100000 bbabb + 1 2 5 ? 5 4 5 3 5 4 5 2 4 4 5 3 1 5 3 4 3 4 ? 2 4 4 1 5 1 1 3 ? 1 3 5 5 1 1 1 3 1 1 4 4 3 5 ? 1 2 5 2 2 5 2 5 + 2 1 5 3 3 - 1 + 4 1 5 1 5 1 5 2 3 ? 4 3 5 1 5 1 5 2 5 1 2 4 ? 1 1 5 3 4 4 3 4 1 5 - 6 - 8 + 2 1 5 1 4 - 13 ? 1 1 5 3 1 2 3 4 1 3 + 5 2 4 1 2 1 4 2 2 1 5 - 16 + 1 1 5 - 18 ...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 4 0 3 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 2 0 8 0 0 0 0 0 0 0 2 0 0 ...
result:
ok 33212 lines
Test #6:
score: 0
Accepted
time: 385ms
memory: 36476kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
0 1 0 1 0 1 0 5 0 4 1 1 1 1 2 0 3 0 0 0 0 1 1 0 0 2 2 0 0 1 5 1 0 0 3 3 5 2 5 0 8 2 2 2 13 2 2 0 2 4 11 9 5 3 14 4 9 19 12 4 12 11 6 7 8 2 22 7 3 20 7 9 6 0 5 5 17 2 9 9 0 2 7 10 11 0 9 3 4 5 12 6 10 0 2 21 2 9 1 3 1 2 2 10 22 8 21 4 3 16 3 8 2 12 9 0 2 12 4 5 19 16 7 5 4 4 3 8 5 11 4 6 5 13 0 6 5 1...
result:
ok 33583 lines
Test #7:
score: 0
Accepted
time: 188ms
memory: 37292kb
input:
100000 100000 baabbabaabaaaabbaaababaaabbbbbaabbababbabbbaabbaaabbbbababaababbbbbababaabaaabaaababaabbbbaaababbbbabaabbaaaaaabbbabbbabababababaabbabbbbbaaabababbbaabababbbaaababaabbaaaabbabbaabbababaabbaaaababaabbbbbababbaaabbbaababbaaaaaabbbbabbbbbbabbaabababbbaaaaaabbabbabaaaaaabbbaaaaaabaabaaabab...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 33381 lines
Test #8:
score: 0
Accepted
time: 436ms
memory: 38528kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
2 2 0 2 1 1 2 2 2 2 0 0 0 0 0 1 0 0 1 0 0 0 2 2 2 0 1 0 0 0 0 1 0 2 3 0 1 0 1 0 0 1 1 2 2 2 1 1 1 0 0 0 2 0 3 0 0 0 0 0 1 2 0 0 1 1 0 0 0 1 1 2 0 2 1 2 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 2 2 1 2 4 3 2 0 2 0 0 1 4 0 0 1 1 5 1 0 1 0 0 2 1 0 3 3 1 0 1 1 2 2 3 0 1 3 7 6 0 7 1 1 1 5 2 5 0 2 6 2 2 2 5 ...
result:
ok 33565 lines
Test #9:
score: 0
Accepted
time: 168ms
memory: 38488kb
input:
100000 100000 aaabbbabbaababbbbbbaaababbbaaaaaabbaaaabababbabababbabbabbbaababbbbabaabaaabbaaabbabababbaaabbabbaaaaabbabababbaaaaababbbbabbabaaabbbaabaabbbaaababbbbbabaaabaaaaabbaabaabbabababbabaaabbbbbbbbaababaabbbabaabbabaaabbbbbababaaabbbbbaaaaaaabbbabbbaabbaabbaaaaaaabbbaabbbaabbaaaababbabaababb...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 33118 lines
Test #10:
score: 0
Accepted
time: 442ms
memory: 38592kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
0 1 0 0 0 2 0 0 0 0 0 0 0 1 0 0 1 0 0 3 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 4 0 1 0 0 0 0 2 0 3 4 4 5 8 7 9 5 0 9 3 8 2 9 0 5 7 1 7 9 0 1 4 1 5 8 5 1 0 0 5 0 4 12 0 9 5 11 10 3 1 8 1 9 2 1 0 5 5 5 0 2 5 1 1 0 0 12 8 11 11 1 4 11 10 3 7 9 9 4 12 11 5 9 6 1 2 8 10 11 4 17 11 6 3 2 4 1 1 3 1 3 2 3 6 5 4 8 12...
result:
ok 33215 lines
Test #11:
score: 0
Accepted
time: 177ms
memory: 37528kb
input:
100000 100000 mwtmtwnsgaynckkprtjhfnmyzylblnkmrismcyyksqxcikyhrsannbmflvloshydnfvydmuoyphxpjgxsfmyqozidivsigleuvmnyniccdqjekyzjtytudpjbwjmsulfipurvjuxququmkfbrigctewalryoiilmqapofcwpllcwjnzmbtirmfmyhbuqkwqhzidrqbxnulklkjmrnzzclykjoflrbimnshtruucmjiukgvzoekyjnjpkkpwcgrbidyuyodlqaaywfsnbcczuxwsbnrcprq...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 33475 lines
Test #12:
score: 0
Accepted
time: 323ms
memory: 35424kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
0 0 1 1 1 1 3 1 3 4 3 3 4 5 7 4 4 4 5 3 4 6 1 0 4 4 12 3 9 9 9 3 7 10 6 9 2 9 4 8 8 7 4 7 7 6 1 5 6 6 4 5 4 3 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 2 0 0 0 0 0 0 0 0 0 0 1 0 1 1 3 1 1 1 4 4 1 0 4 3 2 0 2 1 0 0 0 0 6 5 0 2 4 2 0 0 0 0 1 0 1 0 0 0 2 4 4 1 3 5 1 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 2 2 3 1 ...
result:
ok 33689 lines
Test #13:
score: 0
Accepted
time: 277ms
memory: 36244kb
input:
100000 100000 bbbbbaabbbbbaaabaabaaabbbbaabaaabaabbababbaaaaaaaabbababbbbabbababaabbabaabbaaaabbbbabaabbababbbbbbbaaabaabbabbbbbbaaaaababaaabbbabbaabaabaaabbbabbaaabaaaababbaaabaabbabaaaaaaababababbbbaabbaaaabaabbbbaaaababbabbbbabaabbbaaabbbaabaaabbbaaabaabbbbbabbaaabbaabbabbaababbbabbababbabbaabbbb...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 33438 lines
Test #14:
score: 0
Accepted
time: 144ms
memory: 34288kb
input:
100000 100000 aaabbbbabbaababbabaabbabababaaaaabbababababaabbaaabbbaaaaaabaaabbabbabbbabaabbaabbabbbbbbbaabaaababaaaaabaaaabbbaaaabbaabbaabbbbaaababbabababbaaaaabbbababababaabaabababbabbbbbabbabbbbaaababbbbaabbaaabababaabbbaaabaaaabbabbaabbbaabbbbabbbababbbabaabbaababaaaabbaabaaabbaaabaaaaabbbbbbbab...
output:
0 0 0 0 0 0 0 2 1 4 0 0 1 1 0 0 0 2 0 0 0 8 2 0 2 0 0 0 0 0 0 7 0 0 0 0 10 5 4 4 0 1 4 0 0 2 4 4 0 0 0 6 0 4 0 0 0 7 4 7 3 5 0 0 0 7 0 7 7 0 8 7 3 0 0 11 0 0 4 11 0 2 2 0 11 9 2 11 3 2 12 3 0 13 0 0 3 0 4 5 0 0 0 4 6 0 0 6 0 4 4 0 0 0 5 5 0 0 6 0 7 0 7 8 7 0 6 6 7 7 7 6 17 6 8 7 7 3 15 0 14 6 0 0 14...
result:
ok 33321 lines
Test #15:
score: 0
Accepted
time: 1ms
memory: 4084kb
input:
5 1000 glbdh + 2 2 2 1 2 ? 2 1 2 3 4 1 1 5 ? 1 3 4 3 2 3 4 4 1 5 - 1 ? 1 1 2 2 1 2 1 4 + 1 1 3 + 2 1 4 1 2 ? 2 4 5 1 2 3 2 3 3 4 1 2 ? 2 4 4 1 1 2 3 4 1 3 ? 1 1 2 1 1 3 - 7 + 1 1 5 ? 1 3 3 1 1 2 ? 3 3 4 4 4 2 3 1 1 2 + 3 1 5 2 5 1 2 ? 1 1 1 3 1 2 3 3 1 2 ? 2 4 5 3 3 2 3 3 1 2 ? 1 2 3 2 3 4 1 2 ? 1 1...
output:
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 1 0 0 0 9 0 0 0 0 3 0 1 0 1 0 1 11 0 0 11 0 0 0 0 0 0 12 0 12 0 0 1 0 0 1 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 3 0 0 13 0 0 0 0 13 0 0 0 0 0 1 0 0 0 0 0 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 525 lines
Test #16:
score: 0
Accepted
time: 390ms
memory: 39456kb
input:
100000 100000 mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm...
output:
0 0 0 1 0 0 0 2 0 0 0 0 2 0 0 0 0 1 0 0 2 0 0 1 1 1 1 0 1 2 2 0 2 1 1 1 0 2 1 1 1 1 1 1 0 2 3 3 1 1 1 1 4 1 3 4 0 2 2 2 2 3 2 3 2 0 2 1 3 4 4 3 1 4 2 0 0 3 2 3 3 3 2 3 0 3 3 3 3 3 5 4 0 4 3 4 3 4 4 1 3 3 4 5 4 5 1 6 5 6 8 6 3 6 8 6 3 5 2 1 6 4 3 6 3 1 1 3 4 3 5 8 4 3 5 6 3 6 1 7 3 7 8 6 4 7 4 3 1 5 ...
result:
ok 49940 lines
Test #17:
score: 0
Accepted
time: 545ms
memory: 43024kb
input:
100000 100000 dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd...
output:
0 6 5 7 5 8 6 6 17 13 14 20 26 23 16 21 20 17 39 26 31 32 46 39 36 52 36 28 28 28 26 29 46 53 48 55 18 43 44 40 49 25 59 42 57 60 42 36 65 50 52 59 25 56 42 42 16 77 43 42 65 57 57 52 44 48 42 19 43 72 65 56 101 69 37 69 73 106 72 55 66 22 70 60 40 73 81 78 60 79 94 63 74 62 74 78 110 76 107 113 108...
result:
ok 9964 lines
Test #18:
score: 0
Accepted
time: 304ms
memory: 43228kb
input:
100000 100000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
output:
0 0 1 1 0 0 0 2 2 0 0 1 2 2 0 0 3 3 3 2 0 1 3 0 1 0 2 1 1 1 2 5 4 3 4 3 3 1 3 1 2 1 5 2 3 2 3 5 2 5 3 1 5 3 1 3 1 1 2 4 4 1 5 1 1 2 3 3 3 4 2 5 3 2 2 4 4 2 4 3 3 5 4 7 4 8 6 8 5 4 4 4 6 3 4 7 5 4 9 6 6 5 7 7 5 6 6 5 5 5 6 8 6 5 5 4 7 4 7 4 4 5 4 5 4 8 4 4 5 5 4 8 4 8 8 8 4 7 9 5 7 6 7 6 6 6 8 6 10 6...
result:
ok 90061 lines
Test #19:
score: 0
Accepted
time: 399ms
memory: 41240kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
0 0 0 0 0 0 0 0 0 0 0 1 0 0 3 0 0 1 0 1 0 0 1 3 2 0 2 3 1 0 2 3 0 0 0 0 3 3 3 0 5 2 0 3 0 1 3 1 0 1 1 0 3 3 3 0 6 3 0 3 0 0 1 3 3 2 3 4 0 1 3 1 3 1 1 6 5 4 8 2 1 3 4 3 0 0 6 8 10 1 4 11 2 4 0 0 0 4 3 9 3 2 10 10 7 3 1 1 3 8 5 0 3 1 8 1 3 0 8 1 6 1 4 1 8 8 6 1 7 0 1 6 9 1 6 4 3 1 2 6 7 1 9 10 3 7 2 2...
result:
ok 49932 lines
Test #20:
score: 0
Accepted
time: 559ms
memory: 42740kb
input:
100000 100000 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz...
output:
1 1 1 0 1 2 2 1 4 4 4 6 6 7 7 9 12 12 11 15 8 21 3 4 8 8 26 11 15 11 20 21 22 29 14 26 25 31 34 26 19 11 29 33 17 20 20 27 33 29 29 43 31 33 33 16 35 30 17 24 40 36 41 19 33 38 51 32 64 28 21 50 42 41 46 29 48 51 62 56 30 45 62 37 54 38 22 43 38 45 43 40 59 53 73 73 72 45 68 27 68 64 62 72 51 65 39 ...
result:
ok 10030 lines
Test #21:
score: 0
Accepted
time: 300ms
memory: 43068kb
input:
100000 100000 pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp...
output:
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 1 2 0 0 0 1 1 1 1 1 0 1 3 1 1 1 2 0 1 2 3 3 0 1 1 1 1 1 1 2 2 2 0 2 3 1 1 1 1 0 1 1 0 2 0 2 0 1 0 2 3 2 1 1 1 1 1 5 3 0 2 2 2 0 2 2 2 1 2 4 5 2 2 5 2 1 2 5 0 2 5 3 5 5 0 2 2 3 0 4 2 4 0 2 1 2 1 2 2 1 0 2 1 3 1 0 2 0 2 2 0 3 3 3 5 2 2 5 3 6 5 3 3 ...
result:
ok 90160 lines
Test #22:
score: 0
Accepted
time: 208ms
memory: 36756kb
input:
100000 100000 faxyuxswncplvrzynzvlbjqvkdhqfmdddimahxygchjxwqaouebuiijkydypsvhlqeoelcnizmzcnuzvxzqilitcmbrhwjtbastbqyktczoarrihswnbsjtzvkrdjkwzijqkcziwqndcfgyvpepsokrgtlvrwxwjbtctdluemgbpzneomxcqdxxaoxdrgdzrherrygznacprcimyudgbjpelkpxotckckzihjuxnlmkczsutackpunsfnkwvhkadjfnhmvplqfgzmkssoacpuxaipepwro...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ...
result:
ok 49806 lines
Test #23:
score: 0
Accepted
time: 267ms
memory: 42180kb
input:
100000 100000 twdczjujsjrmpsipsunndczjujsjrmpsipsuwynwdczjujsjrmpsipsuwjwdczjujsjrmpsipsuyhtwdczjujsjrmpsipsuwwddczjujsjrmpsipsudczjujsjrmpsipsuybtwdczjujsjrmpsipsuwexdczjujsjrmpsipsuwevtwdczjujsjrmpsipsuwexatwdczjujsjrmpsipsuapwdczjujsjrmpsipsuwepwdczjujsjrmpsipsuwowdczjujsjrmpsipsudczjujsjrmpsipsu...
output:
0 1 0 0 0 1 0 0 1 1 7 0 0 0 0 3 3 0 3 3 1 1 0 0 0 0 0 3 9 13 0 14 5 0 2 10 6 5 2 9 3 9 3 5 6 2 1 0 4 2 1 0 0 10 3 5 2 0 7 0 30 27 0 3 13 0 0 0 1 0 22 0 0 1 0 0 27 0 35 1 0 1 17 0 0 0 1 10 0 0 0 2 2 15 0 52 0 4 14 0 0 36 6 0 25 0 12 0 6 1 0 1 0 0 0 3 9 2 0 60 38 16 15 11 0 0 0 2 13 0 0 6 0 7 0 0 0 25...
result:
ok 9909 lines
Test #24:
score: 0
Accepted
time: 126ms
memory: 42064kb
input:
100000 100000 gqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxicygqxi...
output:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 9 9 9 10 10 11 11 11 11 11 11 11 11 12 12 12 12 12 12 13 13 13 13 13 13 13 14 14 14 15 15 15 15 15 1...
result:
ok 90066 lines
Test #25:
score: 0
Accepted
time: 238ms
memory: 38664kb
input:
100000 100000 nbaiostoyrvtrkngnuatnddlyjzqnfgufkqtmahrkmxxstxnqszjxibrnymsyujvzvazdmernpfoapfefjnbberzsmfmfqjwyyrqmbgdzppkratnddlyjzqnfgufkqtmahrkmxxstxnqszjxibrnymsyujvzvazdmernpfoapfefjnbberzsmfmfqjwyyrqvazynjzqnfgufkqtmahrkmxxstxnqszjxibrnymsyujvzvazdmernpfoapfefjnbberzsjzqnfgufkqtmahrkmxxstxnqsz...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 50106 lines
Test #26:
score: 0
Accepted
time: 235ms
memory: 42692kb
input:
100000 100000 avrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpogavrzpo...
output:
2 2 13 28 31 64 83 95 108 119 121 127 134 141 157 158 162 164 175 181 181 195 201 201 209 210 215 218 253 259 263 263 273 274 280 303 310 317 318 325 328 342 360 368 376 392 393 420 427 431 434 440 456 457 485 501 502 533 556 593 601 601 605 606 614 617 644 654 687 700 721 723 728 728 731 731 738 74...
result:
ok 9852 lines
Test #27:
score: 0
Accepted
time: 159ms
memory: 41680kb
input:
100000 100000 nzqcglfwczqmzqcglfwczazqcglfwczzmzqcglfwczzqcglfwczpmzqcglfwczzqcglfwcxmzqcglfwcznzqcglfwczqcglfwcmzqcglfwczmzqcglfwcjmzqcglfwczzqcglfwczrzqcglfwczqcglfwczqcglfwczmzqcglfwczwzqcglfwczqcglfwcjzqcglfwcmzqcglfwcmzqcglfwczzqcglfwcizqcglfwcomzqcglfwcmzqcglfwczzqcglfwcjmzqcglfwczmzqcglfwczmz...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 2 0 1 0 0 3 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 3 0 0 0 0 0 0 0 1 2 0 0 0 0 1 0 1 0 1 0 0 ...
result:
ok 90005 lines
Test #28:
score: 0
Accepted
time: 409ms
memory: 39076kb
input:
100000 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
5379 21600 8676 17796 6561 7062 8794 24490 12428 13642 26349 12930 17230 4054 29012 19503 23951 2084 14612 6542 11110 18521 5532 30725 21338 30107 893 12051 20828 7845 32580 8063 4190 21112 8005 33480 15470 3466 1311 10240 13981 29868 3358 35905 19687 9180 46665 11173 4030 5610 14002 22315 28887 629...
result:
ok 49879 lines
Extra Test:
score: -3
Extra Test Failed : Time Limit Exceeded on 2
input:
100000 100000 acbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...