Submission #68327282


Source Code Expand

#pragma GCC optimize "-O3,omit-frame-pointer,inline,unroll-all-loops,fast-math"

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;

// ===== MACROS =====
#define FOR(i, n, m) for (int i = n; i < (int)m; ++i)
#define REP(i, n) FOR (i, 0, n)
#define REP_1(i, n) for (int i = 1; i <= (int)n; ++i)
#define RFOR(i, n, m) for (int i = (int)n - 1; i >= (int)m; --i)
#define RREP(i, n) RFOR(i, n, 0)
#define RREP_1(i, n) for (int i = (int)n; i >= 1; --i)

#define ALL(v) v.begin(), v.end()
#define RALL(v) v.rbegin(), v.rend()
#define SIZE(v) (int)v.size()
#define EMPTY(v) v.empty()
#define SORT(v) sort(ALL(v))
#define RSORT(v) sort(RALL(v))
#define REVERSE(v) reverse(ALL(v))
#define UNIQUE(v) (SORT(v), v.erase(unique(ALL(v)), v.end()))

#define PB push_back
#define EB emplace_back
#define MP make_pair

// ===== UTILITY MACROS =====
#define YES() cout << "YES\n"
#define NO() cout << "NO\n"
#define Yes() cout << "Yes\n"
#define No() cout << "No\n"
#define YESNO(cond) cout << ((cond) ? "YES" : "NO") << '\n'
#define YesNo(cond) cout << ((cond) ? "Yes" : "No") << '\n'

#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))

#define FASTIO() \
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define PRECISION(n) cout << fixed << setprecision(n)

// ===== TYPE ALIASES =====
using P = pair<int, int>;
using ll = long long;
using ull = unsigned long long;
using ld = long double;

template <class T>
using min_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
using max_queue = priority_queue<T>;

struct uint64_hash {
    static inline uint64_t rotr(uint64_t x, unsigned k) {
        return (x >> k) | (x << (8U * sizeof(uint64_t) - k));
    }
    static inline uint64_t hash_int(uint64_t x) noexcept {
        auto h1 = x * (uint64_t)(0xA24BAED4963EE407);
        auto h2 = rotr(x, 32U) * (uint64_t)(0x9FB21C651E98DF25);
        auto h = rotr(h1 + h2, 32U);
        return h;
    }
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM =
            std::chrono::steady_clock::now().time_since_epoch().count();
        return hash_int(x + FIXED_RANDOM);
    }
};

template <typename K, typename V, typename Hash = uint64_hash>
using hash_map = __gnu_pbds::gp_hash_table<K, V, Hash>;
template <typename K, typename Hash = uint64_hash>
using hash_set = hash_map<K, __gnu_pbds::null_type, Hash>;

template <typename T, size_t MAXSIZE>
struct fast_queue {
    T data[MAXSIZE];
    size_t head, tail;
    fast_queue() : head(0), tail(0) {}
    inline void push(const T &x) { data[tail++] = x; }
    inline void emplace(T &&x) { data[tail++] = std::move(x); }
    inline T front() const { return data[head]; }
    inline void pop() { head++; }
    inline bool empty() const { return head == tail; }
    inline size_t size() const { return tail - head; }
    inline void clear() { head = tail = 0; }
    inline T *begin() { return data + head; }
    inline T *end() { return data + tail; }
    inline const T *begin() const { return data + head; }
    inline const T *end() const { return data + tail; }
};

template <typename K, typename V, size_t MAXSIZE>
struct fast_map {
    struct Entry {
        K key;
        V value;
        bool used;
        Entry() : used(false) {}
    };
    vector<Entry> data;
    size_t element_count;

    fast_map() : data(MAXSIZE), element_count(0) {}

    inline size_t hash(const K &key) const {
        return std::hash<K>{}(key) % data.size();
    }

    inline size_t find_pos(const K &key) const {
        size_t pos = hash(key);
        while (data[pos].used && data[pos].key != key) {
            pos = (pos + 1) % MAXSIZE;
        }
        return pos;
    }

    inline V &operator[](const K &key) {
        size_t pos = find_pos(key);
        if (!data[pos].used) {
            data[pos].key = key;
            data[pos].value = V{};
            data[pos].used = true;
            element_count++;
        }
        return data[pos].value;
    }

    inline const V &at(const K &key) const {
        size_t pos = find_pos(key);
        if (!data[pos].used || data[pos].key != key) {
            throw std::out_of_range("FastHashTable: key not found");
        }
        return data[pos].value;
    }

    inline V &at(const K &key) {
        size_t pos = find_pos(key);
        if (!data[pos].used || data[pos].key != key) {
            throw std::out_of_range("FastHashTable: key not found");
        }
        return data[pos].value;
    }

    inline size_t count(const K &key) const {
        size_t pos = find_pos(key);
        return (data[pos].used && data[pos].key == key) ? 1 : 0;
    }

    inline bool erase(const K &key) {
        size_t pos = find_pos(key);
        if (data[pos].used && data[pos].key == key) {
            data[pos].used = false;
            element_count--;
            return true;
        }
        return false;
    }

    inline size_t size() const { return element_count; }
    inline bool empty() const { return element_count == 0; }

    inline bool find(const K &key, V &result) const {
        if (count(key)) {
            result = at(key);
            return true;
        }
        return false;
    }

    inline bool contains(const K &key) const { return count(key) > 0; }

    inline void clear() {
        for (size_t i = 0; i < data.size(); i++) {
            data[i].used = false;
        }
        element_count = 0;
    }

    struct iterator {
        Entry *ptr;
        Entry *end_ptr;

        iterator(Entry *p, Entry *e) : ptr(p), end_ptr(e) {
            while (ptr < end_ptr && !ptr->used) ptr++;
        }

        pair<K, V> operator*() const { return {ptr->key, ptr->value}; }
        iterator &operator++() {
            do {
                ptr++;
            } while (ptr < end_ptr && !ptr->used);
            return *this;
        }
        bool operator!=(const iterator &other) const {
            return ptr != other.ptr;
        }
        bool operator==(const iterator &other) const {
            return ptr == other.ptr;
        }
    };

    iterator begin() {
        return iterator(data.data(), data.data() + data.size());
    }
    iterator end() {
        return iterator(data.data() + data.size(), data.data() + data.size());
    }
};

// ===== NUMBER SORTING =====
inline void radix_sort_impl(vector<int> &arr) {
    constexpr int BITS = 8;
    constexpr int BUCKETS = 1 << BITS;
    constexpr int MASK = BUCKETS - 1;

    vector<int> temp(arr.size());
    vector<int> count(BUCKETS);

    for (int shift = 0; shift < 32; shift += BITS) {
        fill(count.begin(), count.end(), 0);
        for (int x : arr) count[(x >> shift) & MASK]++;
        for (int i = 1; i < BUCKETS; i++) count[i] += count[i - 1];
        for (int i = arr.size() - 1; i >= 0; i--) {
            int x = arr[i];
            temp[--count[(x >> shift) & MASK]] = x;
        }
        arr = temp;
    }
}

inline void counting_sort_impl(vector<int> &arr, int max_val) {
    vector<int> count(max_val + 1, 0);
    for (auto x : arr) count[x]++;

    int pos = 0;
    for (int i = 0; i <= max_val; i++) {
        while (count[i]--) {
            arr[pos++] = i;
        }
    }
}

void fast_sort(vector<int> &arr) {
    if (arr.empty()) return;
    int max_val = *max_element(arr.begin(), arr.end());
    if (max_val <= (int)arr.size()) {
        counting_sort_impl(arr, max_val);
    } else {
        radix_sort_impl(arr);
    }
}

// ===== CONSTANTS =====
constexpr int INF = 1000000100;
constexpr ll INFL = (ll)1000000000000001000LL;
constexpr ll MOD = 998244353;
constexpr ld PI = 3.141592653589793238462643383279;
constexpr ld EPS = 1e-9;

// ===== DIRECTIONS =====
constexpr int dx4[] = {0, 1, 0, -1};
constexpr int dy4[] = {1, 0, -1, 0};
constexpr int dx8[] = {0, 1, 1, 1, 0, -1, -1, -1};
constexpr int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1};

// ===== DEBUG MACROS =====
const std::string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m",
                  BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m",
                  NORMAL_CROSSED = "\033[0;9;37m",
                  RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";

#ifdef LOCAL
#define dbg(x)                                                         \
    std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x)      \
              << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ \
              << COLOR_RESET << std::endl
#define dbgif(cond, x)                                                      \
    ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) \
                        << NORMAL_FAINT << " (L" << __LINE__ << ") "        \
                        << __FILE__ << COLOR_RESET << std::endl             \
            : std::cerr)
#define msg(s)                                                          \
    std::cerr << BRIGHT_GREEN << s << NORMAL_FAINT << " (L" << __LINE__ \
              << ") " << __FILE__ << COLOR_RESET << std::endl
#else
#define dbg(x) 0
#define dbgif(cond, x) 0
#define msg(s) 0
#endif

// ===== PAIR OPERATORS =====
template <class T1, class T2>
std::pair<T1, T2> operator+(const std::pair<T1, T2> &l,
                            const std::pair<T1, T2> &r) {
    return std::make_pair(l.first + r.first, l.second + r.second);
}
template <class T1, class T2>
std::pair<T1, T2> operator-(const std::pair<T1, T2> &l,
                            const std::pair<T1, T2> &r) {
    return std::make_pair(l.first - r.first, l.second - r.second);
}

// ===== I/O OPERATORS =====
template <class IStream, class T>
IStream &operator>>(IStream &is, std::vector<T> &vec) {
    for (auto &v : vec) is >> v;
    return is;
}
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz>
OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH>
OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U>
OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U>
OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV>
OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH>
OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T>
OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::vector<T> &vec) {
    os << '[';
    for (auto v : vec) os << v << ',';
    os << ']';
    return os;
}
template <class OStream, class T, size_t sz>
OStream &operator<<(OStream &os, const std::array<T, sz> &arr) {
    os << '[';
    for (auto v : arr) os << v << ',';
    os << ']';
    return os;
}
template <class... T>
std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) {
    std::apply([&is](auto &&...args) { ((is >> args), ...); }, tpl);
    return is;
}
template <class OStream, class... T>
OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) {
    os << '(';
    std::apply([&os](auto &&...args) { ((os << args << ','), ...); }, tpl);
    return os << ')';
}
template <class OStream, class T, class TH>
OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) {
    os << '{';
    for (auto v : vec) os << v << ',';
    os << '}';
    return os;
}
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::deque<T> &vec) {
    os << "deq[";
    for (auto v : vec) os << v << ',';
    os << ']';
    return os;
}
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::set<T> &vec) {
    os << '{';
    for (auto v : vec) os << v << ',';
    os << '}';
    return os;
}
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::multiset<T> &vec) {
    os << '{';
    for (auto v : vec) os << v << ',';
    os << '}';
    return os;
}
template <class OStream, class T>
OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) {
    os << '{';
    for (auto v : vec) os << v << ',';
    os << '}';
    return os;
}
template <class OStream, class T, class U>
OStream &operator<<(OStream &os, const std::pair<T, U> &pa) {
    return os << '(' << pa.first << ',' << pa.second << ')';
}
template <class OStream, class TK, class TV>
OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) {
    os << '{';
    for (auto v : mp) os << v.first << "=>" << v.second << ',';
    os << '}';
    return os;
}
template <class OStream, class TK, class TV, class TH>
OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) {
    os << '{';
    for (auto v : mp) os << v.first << "=>" << v.second << ',';
    os << '}';
    return os;
}

// ===== BIT OPERATIONS =====
__attribute__((always_inline)) inline ull bit(ull x) { return 1ull << x; }
__attribute__((always_inline)) inline void setbit(ull &a, int b,
                                                  ull value = 1) {
    a = (a & ~bit(b)) | (value << b);
}
__attribute__((always_inline)) inline ull getbit(ull a, int b) {
    return (a >> b) & 1;
}
__attribute__((always_inline)) inline ull lsb(ull a) {
    return __builtin_ctzll(a);
}
__attribute__((always_inline)) inline int msb(uint64_t bb) {
    return __builtin_clzll(bb) ^ 63;
}

// ===== CHMAX/CHMIN =====
template <typename T>
inline bool chmax(T &a, T b) {
    return a < b && (a = b, true);
}
template <typename T>
inline bool chmin(T &a, T b) {
    return a > b && (a = b, true);
}

// ===== TIMER =====
struct Timer {
    chrono::time_point<chrono::high_resolution_clock> start_time;
    chrono::duration<double> elapsed;
    Timer() : elapsed(0) {}
    double elapsed_seconds() const {
        return elapsed.count() +
               chrono::duration<double>(chrono::high_resolution_clock::now() -
                                        start_time)
                   .count();
    }
    void reset() { elapsed = chrono::duration<double>::zero(); }
};

// ===== RANDOM NUMBER GENERATOR =====
struct RNG {
    uint64_t s[2];
    RNG(ull seed) { reset(seed); }
    RNG() { reset(0); }
    using result_type = int;
    static __attribute__((always_inline)) inline uint64_t rotl(const uint64_t x,
                                                               int k) {
        return (x << k) | (x >> (64 - k));
    }
    inline void reset(ull seed) {
        struct splitmix64_state {
            ull s;
            ull splitmix64() {
                ull result = (s += 0x9E3779B97f4A7C15);
                result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
                result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
                return result ^ (result >> 31);
            }
        };
        splitmix64_state sm{seed};
        s[0] = sm.splitmix64();
        s[1] = sm.splitmix64();
    }
    ull next() {
        const uint64_t s0 = s[0];
        uint64_t s1 = s[1];
        const uint64_t result = rotl(s0 * 5, 7) * 9;
        s1 ^= s0;
        s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16);
        s[1] = rotl(s1, 37);
        return result;
    }
    inline int operator()() { return next(); }
    inline int operator()(int r) { return next() % r; }
    inline int operator()(int l, int r) { return l + (next() % (r - l + 1)); }
    inline double d() { return (double)operator()() / 4294967296.0; }
    inline double d(double l, double r) { return l + d() * (r - l); }
    template <class T>
    void shuffle(vector<T> &v) {
        int sz = v.size();
        for (int i = sz; i > 1; i--) {
            int p = operator()(i);
            swap(v[i - 1], v[p]);
        }
    }
    template <class T>
    inline T sample(vector<T> const &v) {
        return v[operator()(v.size())];
    }
} rng;

// ===== COMBINATORICS =====
struct modint {
    ll n;

   public:
    modint() : n(0) {}
    modint(ll x) : n(((x % MOD) + MOD) % MOD) {}

    ll val() const { return n; }

    modint pow(ll m) const {
        modint r = 1, a = *this;
        while (m > 0) {
            if (m & 1) r *= a;
            a *= a;
            m >>= 1;
        }
        return r;
    }

    modint inv() const { return pow(MOD - 2); }

    modint &operator++() { return *this += 1; }
    modint &operator--() { return *this -= 1; }
    modint operator++(int) {
        modint ret = *this;
        ++*this;
        return ret;
    }
    modint operator--(int) {
        modint ret = *this;
        --*this;
        return ret;
    }

    modint operator+() const { return *this; }
    modint operator-() const { return modint() - *this; }

    friend bool operator==(const modint &lhs, const modint &rhs) {
        return lhs.n == rhs.n;
    }
    friend bool operator!=(const modint &lhs, const modint &rhs) {
        return lhs.n != rhs.n;
    }
    friend bool operator<(const modint &lhs, const modint &rhs) {
        return lhs.n < rhs.n;
    }
    friend bool operator<=(const modint &lhs, const modint &rhs) {
        return lhs.n <= rhs.n;
    }
    friend bool operator>(const modint &lhs, const modint &rhs) {
        return lhs.n > rhs.n;
    }
    friend bool operator>=(const modint &lhs, const modint &rhs) {
        return lhs.n >= rhs.n;
    }

    friend modint &operator+=(modint &lhs, const modint &rhs) {
        lhs.n += rhs.n;
        if (lhs.n >= MOD) lhs.n -= MOD;
        return lhs;
    }
    friend modint &operator-=(modint &lhs, const modint &rhs) {
        lhs.n -= rhs.n;
        if (lhs.n < 0) lhs.n += MOD;
        return lhs;
    }
    friend modint &operator*=(modint &lhs, const modint &rhs) {
        lhs.n = (lhs.n * rhs.n) % MOD;
        return lhs;
    }
    friend modint &operator/=(modint &lhs, const modint &rhs) {
        return lhs *= rhs.inv();
    }

    friend modint operator+(const modint &lhs, const modint &rhs) {
        modint res = lhs;
        res += rhs;
        return res;
    }
    friend modint operator-(const modint &lhs, const modint &rhs) {
        modint res = lhs;
        res -= rhs;
        return res;
    }
    friend modint operator*(const modint &lhs, const modint &rhs) {
        modint res = lhs;
        res *= rhs;
        return res;
    }
    friend modint operator/(const modint &lhs, const modint &rhs) {
        modint res = lhs;
        res /= rhs;
        return res;
    }

    friend istream &operator>>(istream &is, modint &m) {
        ll x;
        is >> x;
        m = modint(x);
        return is;
    }
    friend ostream &operator<<(ostream &os, const modint &m) {
        return os << m.n;
    }
};

using mi = modint;

struct Comb {
    vector<mi> fact, inv_fact;
    Comb(int n) : fact(n + 1), inv_fact(n + 1) {
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }

        inv_fact[n] = fact[n].inv();
        for (int i = n - 1; i >= 0; i--) {
            inv_fact[i] = inv_fact[i + 1] * (i + 1);
        }
    }
    mi C(int n, int k) {
        if (n < 0 || k < 0 || n < k) return 0;
        return fact[n] * inv_fact[k] * inv_fact[n - k];
    }

    mi P(int n, int k) {
        if (n < 0 || k < 0 || n < k) return 0;
        return fact[n] * inv_fact[n - k];
    }

    mi H(int n, int k) {
        if (n < 0 || k < 0) return 0;
        return C(n + k - 1, k);
    }

    // n! / (k1! * k2! * ... * kn!)
    mi multinomial(int n, const vector<int> &ks) {
        mi res = fact[n];
        for (int k : ks) {
            if (k < 0 || k > n) return 0;
            res *= inv_fact[k];
        }
        return res;
    }

    // 1 / (n + 1) * C(2n, n)
    mi catalan(int n) { return C(2 * n, n) * mi(n + 1).inv(); }
};

// ===== DATA STRUCTURES =====
struct IndexSet {
    vector<int> que;
    vector<int> pos;

    IndexSet(int n) : pos(n, -1) {}

    void add(int v) {
        pos[v] = que.size();
        que.push_back(v);
    }

    void remove(int v) {
        int p = pos[v];
        int b = que.back();
        que[p] = b;
        que.pop_back();
        pos[b] = p;
        pos[v] = -1;
    }

    bool contains(int v) const { return pos[v] != -1; }

    int size() const { return que.size(); }
};

struct UnionFind {
    vector<int> data;
    vector<int> a;
    vector<int> b;

    UnionFind() = default;

    explicit UnionFind(size_t sz) : data(sz, -1), a(sz, 0), b(sz, 0) {}

    int unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return false;
        if (data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        a[x] += a[y];
        b[x] += b[y];
        int ret = min(a[x], b[x]);
        a[x] -= ret;
        b[x] -= ret;
        return ret;
    }

    int find(int k) {
        if (data[k] < 0) return (k);
        return data[k] = find(data[k]);
    }

    int size(int k) { return -data[find(k)]; }

    bool same(int x, int y) { return find(x) == find(y); }

    vector<vector<int>> groups() {
        int n = (int)data.size();
        vector<vector<int>> ret(n);
        for (int i = 0; i < n; ++i) {
            ret[find(i)].emplace_back(i);
        }
        ret.erase(remove_if(begin(ret), end(ret),
                            [&](const vector<int> &v) { return v.empty(); }),
                  end(ret));
        return ret;
    }
};

template <typename Monoid>
struct SegmentTree {
    using S = typename Monoid::S;

   private:
    int n, sz;

    vector<S> seg;

    Monoid m;

   public:
    SegmentTree() = default;

    explicit SegmentTree(Monoid m, int n) : m(m), n(n) {
        sz = 1;
        while (sz < n) sz <<= 1;
        seg.assign(2 * sz, m.e());
    }

    explicit SegmentTree(Monoid m, const vector<S> &v)
        : SegmentTree(m, (int)v.size()) {
        build(v);
    }

    void build(const vector<S> &v) {
        assert(n == (int)v.size());
        for (int k = 0; k < n; k++) seg[k + sz] = v[k];
        for (int k = sz - 1; k > 0; k--) {
            seg[k] = m.op(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    void set(int k, const S &x) {
        k += sz;
        seg[k] = x;
        while (k >>= 1) {
            seg[k] = m.op(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    S get(int k) const { return seg[k + sz]; }

    S operator[](int k) const { return get(k); }

    void apply(int k, const S &x) {
        k += sz;
        seg[k] = m.op(seg[k], x);
        while (k >>= 1) {
            seg[k] = m.op(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    S prod(int l, int r) const {
        if (l >= r) return m.e();
        S L = m.e(), R = m.e();
        for (l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
            if (l & 1) L = m.op(L, seg[l++]);
            if (r & 1) R = m.op(seg[--r], R);
        }
        return m.op(L, R);
    }

    S all_prod() const { return seg[1]; }

    template <typename C>
    int find_first(int l, const C &check) const {
        if (l >= n) return n;
        l += sz;
        S sum = m.e();
        do {
            while ((l & 1) == 0) l >>= 1;
            if (check(m.op(sum, seg[l]))) {
                while (l < sz) {
                    l <<= 1;
                    auto nxt = m.op(sum, seg[l]);
                    if (not check(nxt)) {
                        sum = nxt;
                        l++;
                    }
                }
                return l + 1 - sz;
            }
            sum = m.op(sum, seg[l++]);
        } while ((l & -l) != l);
        return n;
    }

    template <typename C>
    int find_last(int r, const C &check) const {
        if (r <= 0) return -1;
        r += sz;
        S sum = m.e();
        do {
            r--;
            while (r > 1 and (r & 1)) r >>= 1;
            if (check(m.op(seg[r], sum))) {
                while (r < sz) {
                    r = (r << 1) + 1;
                    auto nxt = m.op(seg[r], sum);
                    if (not check(nxt)) {
                        sum = nxt;
                        r--;
                    }
                }
                return r - sz;
            }
            sum = m.op(seg[r], sum);
        } while ((r & -r) != r);
        return -1;
    }
};

struct MinIdxMonoid {
    using S = pair<ll, int>;
    static constexpr S op(const S &a, const S &b) {
        return a.first <= b.first ? a : b;
    }
    static constexpr S e() { return {INFL, -1}; }
};

struct MaxIdxMonoid {
    using S = pair<ll, int>;
    static constexpr S op(const S &a, const S &b) {
        return a.first >= b.first ? a : b;
    }
    static constexpr S e() { return {-INFL, -1}; }
};

template <int N>
struct MatrixMonoid {
    using S = array<array<mi, N>, N>;
    static constexpr S op(const S &a, const S &b) {
        S c = {};
        REP (i, N)
            REP (j, N)
                REP (k, N) {
                    c[i][j] += c[i][j] + a[i][k] * b[k][j];
                }
        return c;
    }
    static constexpr S e() {
        S identity = {};
        REP (i, N) identity[i][i] = 1;
        return identity;
    }
};

struct Monoid {
    // using S = ?;
    // static constexpr S op(const S &a, const S &b) {}
    // static constexpr S e() {}
};

template <int char_size>
struct TrieNode {
    int nxt[char_size];

    int exist;
    vector<int> accept;

    TrieNode() : exist(0) { memset(nxt, -1, sizeof(nxt)); }
};

template <int char_size, int margin>
struct Trie {
    using Node = TrieNode<char_size>;

    vector<Node> nodes;
    int root;

    Trie() : root(0) { nodes.push_back(Node()); }

    void update_direct(int node, int id) { nodes[node].accept.push_back(id); }

    void update_child(int node, int child, int id) { ++nodes[node].exist; }

    void add(const string &str, int str_index, int node_index, int id) {
        if (str_index == str.size()) {
            update_direct(node_index, id);
        } else {
            const int c = str[str_index] - margin;
            if (nodes[node_index].nxt[c] == -1) {
                nodes[node_index].nxt[c] = (int)nodes.size();
                nodes.push_back(Node());
            }
            add(str, str_index + 1, nodes[node_index].nxt[c], id);
            update_child(node_index, nodes[node_index].nxt[c], id);
        }
    }

    void add(const string &str, int id) { add(str, 0, 0, id); }

    void add(const string &str) { add(str, nodes[0].exist); }

    void query(const string &str, const function<void(int)> &f, int str_index,
               int node_index) {
        for (auto &idx : nodes[node_index].accept) f(idx);
        if (str_index == str.size()) {
            return;
        } else {
            const int c = str[str_index] - margin;
            if (nodes[node_index].nxt[c] == -1) return;
            query(str, f, str_index + 1, nodes[node_index].nxt[c]);
        }
    }

    void query(const string &str, const function<void(int)> &f) {
        query(str, f, 0, 0);
    }

    int count() const { return (nodes[0].exist); }

    int size() const { return ((int)nodes.size()); }
};

// ===== INSERT CODE HERE =====

constexpr bool MULTI_TESTCASE = false;

void solve() {
    int n, q;
    cin >> n >> q;
    vector<int> a(n);
    REP (i, n) cin >> a[i];
    sort(ALL(a));
    vector<ll> sum(n, a[0]);
    FOR (i, 1, n) sum[i] = sum[i - 1] + a[i];
    REP (i, q) {
        ll b;
        cin >> b;
        if (a.back() < b) {
            cout << -1 << endl;
            continue;
        }
        int it = lower_bound(ALL(a), b) - a.begin();
        auto ans = sum[it] - a[it] + (n - it) * (b - 1) + 1;
        cout << ans << endl;
    }
}

int main() {
    FASTIO();
    PRECISION(20);
    int t = 1;

    if (MULTI_TESTCASE) cin >> t;
    while (t--) {
        solve();
    }
}

Submission Info

Submission Time
Task C - Flush
User gazelle
Language C++ 23 (gcc 12.2)
Score 350
Code Size 29135 Byte
Status AC
Exec Time 399 ms
Memory 7892 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 350 / 350
Status
AC × 2
AC × 11
Set Name Test Cases
Sample 00-sample-01.txt, 00-sample-02.txt
All 00-sample-01.txt, 00-sample-02.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt
Case Name Status Exec Time Memory
00-sample-01.txt AC 1 ms 3452 KiB
00-sample-02.txt AC 1 ms 3448 KiB
01-01.txt AC 41 ms 3440 KiB
01-02.txt AC 41 ms 3452 KiB
01-03.txt AC 41 ms 3452 KiB
01-04.txt AC 399 ms 7656 KiB
01-05.txt AC 314 ms 6536 KiB
01-06.txt AC 335 ms 7660 KiB
01-07.txt AC 349 ms 7892 KiB
01-08.txt AC 343 ms 7656 KiB
01-09.txt AC 391 ms 7260 KiB