Submission #61572895


Source Code Expand

#pragma region Macros

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,mmx,abm,bmi,bmi2,popcnt,lzcnt")
#pragma GCC target("avx2") // CF, CodeChef, HOJ ではコメントアウト

#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;

// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using lll = mp::cpp_int;
// using lld = mp::cpp_dec_float_50; // 十進50桁. ldは19桁.
// // using lld = mp::cpp_dec_float_100;
// // using lld = mp::number<mp::cpp_dec_float<200>>;
// lld Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(lld a, lld b) { return mp::fabs(a - b) < Beps; }

#define pb emplace_back
#define int ll
#define endl '\n'

using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
const int MOD = 998244353;
// const int MOD = 1000000007;

const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }

const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1, 0}; // → ↓ ← ↑ ↘ ↙ ↖ ↗ 自
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1, 0};

struct Edge {
    using cost_type = int;
    int from, to;
    cost_type cost;
    Edge() {}
    Edge(int to, cost_type cost) : to(to), cost(cost), from(-1) {}
    Edge(int from, int to, cost_type cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge &e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge &e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge &e) { return this->cost < e.cost; }
    bool operator >(const Edge &e) { return this->cost > e.cost; }
};

chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}

struct RNG {
    using state_type = uint32_t;
    using result_type = uint32_t;
    state_type x = 123456789, y = 362436039, z = 521288629, w = 88675123;
    constexpr static double INV_MAX = 1.0 / 0xFFFFFFFF;

    // constexpr RNG(state_type seed = 88675123): w(seed) {}
    RNG() {
        auto now = chrono::high_resolution_clock::now();
        w = static_cast<state_type>(now.time_since_epoch().count() & 0xFFFFFFFF);
    }
    constexpr result_type operator()() {
        state_type t = x ^ (x << 11);
        x = y, y = z, z = w;
        return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
    }

    constexpr result_type Int(state_type a) { // [0, a)
        return ((uint64_t) (*this)() * a) >> 32;
    }
    constexpr result_type Int(state_type a, state_type b) { // [a, b]
        return Int(b - a + 1) + a;
    }

    constexpr double prob() { // [0, 1]
        return (*this)() * INV_MAX;
    }
    constexpr double Double(double a, double b) { // [a, b]
        return prob() * (b - a) + a;
    }
} rng;

namespace bit_function {
    using i64 = ll;
    // using i64 = uint64_t;
    // bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
    i64 lrmask(int l, int r) { return (1LL << r) - (1LL << l); }
    i64 sub_bit(i64 x, int l, int r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
    i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }

    i64 popcount(i64 x) { return __builtin_popcountll(x); }
    i64 popcount(i64 x, int l, int r) { return __builtin_popcountll(sub_bit(x, l, r)); }
    i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); } // 最上位bitより下のみ
    i64 unpopcount(i64 x, int l, int r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); } // 最上位bitより上も含まれうる
    bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; } // xが負のときは常にfalse
    bool is_pow4(i64 x) { return __builtin_popcountll(x) == 1 && __builtin_ctzll(x) % 2 == 0; }
    //bool is_pow4(ll x) { return __builtin_popcountll(x) == 1 && (x&0x55555555); }

    int top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
    int bot_bit(i64 x) { return __builtin_ctzll(x);} // 2^kの位 (x > 0)
    int next_bit(i64 x, int k) { // upper_bound
        x >>= (k + 1);
        int pos = k + 1;
        while (x > 0) {
            if (x & 1) return pos;
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int prev_bit(i64 x, int k) {
        // k = min(k, bit_width(x)); ?
        int pos = 0;
        while (x > 0 && pos < k) {
            if (x & 1) {
                if (pos < k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int kth_bit(i64 x, int k) { // kは1-indexed
        int pos = 0, cnt = 0;
        while (x > 0) {
            if (x & 1) {
                cnt++;
                if (cnt == k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    i64 msb(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
    i64 lsb(i64 x) { return (x & -x); } // mask

    int countl_zero(i64 x) { return __builtin_clzll(x); }
    int countl_one(i64 x) { // countl_oneと定義が異なるので注意
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { k--; ret++; }
        return ret;
    }
    int countr_zero(i64 x) { return __builtin_ctzll(x); } // x=0のとき64
    int countr_one(i64 x) { int ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }
    // int countr_one(ll x) { return __builtin_popcount(x ^ (x & -~x));

    i64 l_one(i64 x) { // 最上位で連なってる1のmask
        if (x == 0) return 0;
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { ret += 1LL << k; k--; }
        return ret;
    }

    int floor_log2(i64 x) { return 63 - __builtin_clzll(x); } // top_bit
    int ceil_log2(i64 x) { return 64 - __builtin_clzll(x - 1); }
    i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // msb
    i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }

    i64 rotl(i64 x, int k) { // 有効bit内でrotate. オーバーフロー注意
        i64 w = bit_width(x); k %= w;
        return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
    i64 rotr(i64 x, int k) {
        i64 w = bit_width(x); k %= w;
        return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
    i64 bit_reverse(i64 x) { // 有効bit内で左右反転
        i64 r = 0, w = bit_width(x);
        for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
        return r;
    }
    // i64 bit_reverse(i64 x, int l, int r) {}

    bool is_palindrome(i64 x) { return x == bit_reverse(x); }
    bool is_palindrome(i64 x, int l, int r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
    i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
    i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット

    i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
    i64 hamming(i64 a, i64 b, int l, int r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
    i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
    i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
    i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数

    i64 next_combination(i64 x) {
        i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzll(x) + 1));
    }
} using namespace bit_function;

namespace util_function {
    namespace Std = std;
    __int128_t POW(__int128_t x, int n) {
        __int128_t ret = 1;
        assert(n >= 0);
        if (x == 1 or n == 0) ret = 1;
        else if (x == -1 && n % 2 == 0) ret = 1;
        else if (x == -1) ret = -1;
        else if (n % 2 == 0) {
            // assert(x < INFL);
            ret = POW(x * x, n / 2);
        } else {
            // assert(x < INFL);
            ret = x * POW(x, n - 1);
        }
        return ret;
    }
    int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
        assert(y != 0);
        if (x >= 0 && y > 0) return x / y;
        if (x >= 0 && y < 0) return x / y - (x % y < 0);
        if (x < 0 && y < 0) return x / y + (x % y < 0);
        return x / y - (x % y < 0); //  (x < 0 && y > 0)
    }
    int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
        assert(y != 0);
        return x - y * per(x, y);
    } // https://yukicoder.me/problems/no/2781
    int floor(int x, int y) { // (ld)x / y 以下の最大の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x >= 0 ? x / y : (x + 1) / y - 1;
    }
    int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x > 0 ? (x - 1) / y + 1 : x / y;
    }
    int round(int x, int y) { // (ld)x / y を小数第1位について四捨五入
        assert(y != 0);
        if (x*y < 0) return -((abs(x) * 2 + abs(y)) / (abs(y) * 2)); // https://www.acmicpc.net/problem/2108
        return (x * 2 + y) / (y * 2);
    }
    int round(int x, int y, int k) { // (ld)x / y を10^kの位に関して四捨五入
        assert(y != 0 && k >= 0);
        if (k == 0) return (x * 2 + y) / (y * 2);
        x /= y * POW(10, k - 1);
        if (x % 10 >= 5) return (x + 10 - x % 10) * POW(10, k - 1);
        return x * POW(10, k - 1);
    }
    int round2(int x, int y) { // 五捨五超入 // 未verify
        assert(y != 0);
        if (y < 0) y = -y, x = -x;
        int z = x / y;
        if ((z * 2 + 1) * y <= y * 2) z++;
        return z;
    }
    int Floor(ld x) { // 未.  負数でも小さい��に丸める
        if (x > -EPS) return (int)(floorl(x + EPS) + EPS);
        return -(int)((ceill(-x - EPS)) + EPS);
    }
    int Ceil(ld x) { // 未.  負数でも大きい方に丸める
        if (x > EPS) return (int)(ceill(x - EPS) + EPS);
        return -(int)((floorl(-x + EPS)) + EPS);
    }
    int Round(ld x) { // 未. 負数でも.5の場合は大きい方に丸める
        if (x > EPS) return (int)(Std::round(x + EPS) + EPS);
        return (int)(Std::round(x + EPS) - EPS);
    }
    // int get(ld x, int k) { // 未. xの10^kの位の桁
    // }
    ld floor(ld x, int k) { // xを10^kの位に関してflooring
        ld d = pow(10, -k);
        return Floor(x * d) / d; // 未verify
    }
    ld ceil(ld x, int k) { // xを10^kの位に関してceiling
        ld d = pow(10, -k);
        return Ceil(x * d) / d; // 未verify
    }
    ld round(ld x, int k) { // xを10^kの位に関して四捨五入.
        ld d = pow(10, -k);
        return Round(x * d) / d;
    }
    // int kth(int x, int y, int k) { // x / yの10^kの位の桁
    // }
    int floor(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return Std::floor(x / y);
        // floor(x) = ceil(x - 1) という話も
    }
    int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
        assert(!equals(y, 0));
        return Std::ceil(x / y);
        // ceil(x) = floor(x + 1)
    }
    int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
        // 未verify. 誤差対策TODO. EPS外してもいいかも。
        assert(!equals(y, 0));
        if (x >= 0 && y > 0) return Std::floor(x / y)+EPS;
        if (x >= 0 && y < 0) return -Std::floor(x / fabs(y));
        if (x < 0 && y < 0) return Std::floor(x / y) + (x - Std::floor(x/y)*y < -EPS);
        return Std::floor(x / y) - (x - Std::floor(x/y)*y < -EPS); //  (x < 0 && y > 0)
    }
    ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
        // 未verify. 誤差対策TODO. -0.0が返りうる。
        assert(!equals(y, 0));
        if (x >= 0) return x - fabs(y)*fabs(per(x, y));
        return x - fabs(y)*floor(x, fabs(y));
    }
    int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
    int modf(ld x) {
        if (x < 0) return ceill(x);
        else return floorl(x);
    }
    // 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
    int seisuu(int x, int y) {
        assert(y != 0);
        return x / y;
    }
    int seisuu(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return (int)(x / y);
    }

    int floor_log(int base, int x) { // log_base{x} のfloor
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now <= x) {
            now *= base;
            if (now <= x) ret++;
        }
        return ret;
    }
    int ceil_log(int base, int x) { // log_base{x} のceil
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now < x) {
            now *= base;
            ret++;
        }
        return ret;
    }

    template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
        return b;
    }
    template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
        return b;
    }

    template <class T> bool chmax(T &a, const T &b) {
        if (a < b) { a = b; return true; } return false;
    }
    template <class T> bool chmin(T &a, const T &b) {
        if (a > b) { a = b; return true; } return false;
    }
    template <class T> bool chmax(pair<T, T> &a, const pair<T, T> &b) {
        if (a.first < b.first or a.first == b.first && a.second < b.second) { a = b; return true; }
        return false;
    }
    template <class T> bool chmin(pair<T, T> &a, const pair<T, T> &b) {
        if (a.first > b.first or a.first == b.first && a.second > b.second) { a = b; return true; }
        return false;
    }
    template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
        return a + b + c - Std::max({a, b, c}) - Std::min({a, b, c});
    }
    template <typename T, typename... Args>
    void Sort(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.begin(), vec.end());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }
    template <typename T, typename... Args>
    void Sortr(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.rbegin(), vec.rend());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }
    template <class T>
    void sort(vector<T> &A, vector<T> &B) {
        vector<pair<T, T>> P(A.size());
        for (int i = 0; i < A.size(); i++) P[i] = {A[i], B[i]};
        sort(P.begin(), P.end());
        for (int i = 0; i < A.size(); i++) A[i] = P[i].first, B[i] = P[i].second;
    }
    template <class T>
    void unique(vector<T> &A, vector<T> &B) {
        vector<T> A2, B2;
        A2.reserve(A.size()); B2.reserve(B.size());
        for (int i = 0; i < A.size(); i++) {
            if (i == 0 or A[i] != A[i - 1] or B[i] != B[i - 1]) {
                A2.push_back(A[i]);
                B2.push_back(B[i]);
            }
        }
    }

    istream &operator >>(istream &is, __int128_t& x) {
        string S; is >> S;
        __int128_t ret = 0;
        int f = 1;
        if (S[0] == '-') f = -1;
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9')
                ret = ret * 10 + S[i] - '0';
        x = ret * f;
        return (is);
    }
    ostream &operator <<(ostream &os, __int128_t x) {
        ostream::sentry s(os);
        if (s) {
            __uint128_t tmp = x < 0 ? -x : x;
            char buffer[128]; char *d = end(buffer);
            do {
                --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
            } while (tmp != 0);
            if (x < 0) { --d; *d = '-'; }
            int len = end(buffer) - d;
            if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
        }
        return os;
    }

    __int128_t sto128(const string &S) {
        __int128_t ret = 0; int f = 1;
        if (S[0] == '-') f = -1;
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
        return ret * f;
    }
    __int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
    __int128_t lcm(__int128_t a, __int128_t b) {
        return a / gcd(a, b) * b;
        // lcmが__int128_tに収まる必要あり
    }

    string to_string(double x, int k) { // 小数第k+1を四捨五入して小数第k位までを出力
    // 切り捨てがほしい場合は to_string(x, k+1) として pop_back() すればよい?
        ostringstream os;
        os << fixed << setprecision(k) << x;
        return os.str();
    }
    string to_string(__int128_t x) {
        string ret = "";
        if (x < 0) { ret += "-"; x *= -1; }
        while (x) { ret += (char)('0' + x % 10); x /= 10; }
        reverse(ret.begin(), ret.end());
        return ret;
    }
    string to_string(char c) { string s = ""; s += c; return s; }
} using namespace util_function;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};

template<typename T>
class Compress {
public:
    int sz = 0;
    vector<T> uniqV;

    Compress() {}

    template<typename... Vecs>
    Compress(const Vecs&... vecs) {
        (uniqV.insert(uniqV.end(), vecs.begin(), vecs.end()), ...);
        sort(uniqV.begin(), uniqV.end());
        uniqV.erase(unique(uniqV.begin(), uniqV.end()), uniqV.end());
        sz = uniqV.size();
    }

    vector<int> zip(const vector<T> &V) {
        vector<int> ret(V.size());
        for (int i = 0; i < V.size(); i++) {
            ret[i] = encode(V[i]);
        }
        return ret;
    }

    vector<T> unzip(const vector<int> &V) {
        vector<T> ret(V.size());
        for (int i = 0; i < V.size(); i++) {
            ret[i] = decode(V[i]);
        }
        return ret;
    }

    int size() { return sz; }

    int encode(T x) {
        auto it = lower_bound(uniqV.begin(), uniqV.end(), x);
        return it - uniqV.begin();
    }

    T decode(int x) {
        if (x < 0 or x >= uniqV.size()) return -1; // xが範囲外の場合
        return uniqV[x];
    }
};

class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};

template<typename T> struct BIT {
    int N;
    vector<T> bit[2];
    BIT(int N_, int x = 0) : N(N_ + 1) {
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0)
            for (int i = 0; i < N; i++) add(i, x);
    }
    BIT(const vector<T> &A) : N(A.size() + 1) {
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = T(0);
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};

template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }

    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }

    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }

    friend istream &operator >>(istream &is, Modint& x) {
        int t; is >> t; x = t; return (is);
    }
    friend ostream &operator <<(ostream &os, const Modint& x) {
        return os << x.val;
    }
};
using mint = Modint<MOD>;

mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}
int modpow(__int128_t x, int n, int mod) {
    if (n == 0 && mod == 1) return 0;
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
// int modinv(__int128_t x, int mod) { //
//     assert(mod > 0);
//     // assert(x > 0);
//     if (x == 1 or x == 0) return 1;
//     return mod - modinv(mod % x, mod) * (mod / x) % mod;
// }

vector<mint> _fac, _finv, _inv;
void COMinit(int N) {
    _fac.resize(N + 1); _finv.resize(N + 1);  _inv.resize(N + 1);
    _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
    for (int i = 2; i <= N; i++) {
        _fac[i] = _fac[i-1] * mint(i);
        _inv[i] = -_inv[MOD % i] * mint(MOD / i);
        _finv[i] = _finv[i - 1] * _inv[i];
    }
}

mint FAC(int N) {
    if (N < 0) return 0; return _fac[N];
}
mint FACinv(int N) {
    if (N < 0) return 0; return _finv[N];
}
mint COM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] * _finv[K] * _finv[N - K];
}
mint COMinv(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _finv[N] * _fac[K] * _fac[N - K];
}
mint MCOM(const vector<int> &V) {
    int N = 0;
    for (int i = 0; i < V.size(); i++) N += V[i];
    mint ret = _fac[N];
    for (int i = 0; i < V.size(); i++) ret *= _finv[V[i]];
    return ret;
}
mint PERM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] *  _finv[N - K];
}
mint NHK(int N, int K) { // initのサイズに注意
    if (N == 0 && K == 0)  return 1;
    return COM(N + K - 1, K);
}

#pragma endregion

struct MST {
    multiset<int> st;
    int os = 0;

    bool insert(int x) {
        st.emplace(x - os);
        return true;
    }
    int front() {
        return *st.begin() + os;
    }
    void add(int x) {
        os += x;
    }
    void pop_front() {
        st.erase(st.find(*st.begin()));
    }
    int size() { return st.size(); }
};

signed main() {
    int N;
    cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; i++) cin >> A[i];

    vector<int> ans(N);
    MST st;
    for (int i = 0; i < N; i++) {
        ans[i] = A[i] + st.size();
        st.add(-1);
        while (st.size() && st.front() <= 0) {
            st.pop_front();
        }
        if (ans[i] > 0) st.insert(ans[i]);
        ans[i] = max(0LL, ans[i] - (N - i - 1));

        // for (auto &x : st.st) cout << x <<" ";
        // cout << endl;
    }

    for (int i = 0; i < (int)ans.size(); i++) {
        cout << ans[i] << (i != (int)ans.size() - 1 ? " " : "\n");
    }
}

Submission Info

Submission Time
Task D - Coming of Age Celebration
User T101010101
Language C++ 17 (gcc 12.2)
Score 400
Code Size 28800 Byte
Status AC
Exec Time 341 ms
Memory 35132 KiB

Compile Error

Main.cpp:1: warning: ignoring ‘#pragma region Macros’ [-Wunknown-pragmas]
    1 | #pragma region Macros
      | 
Main.cpp:744: warning: ignoring ‘#pragma endregion ’ [-Wunknown-pragmas]
  744 | #pragma endregion
      | 
Main.cpp:36:1: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
   36 | const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
      | ^~~~~
Main.cpp: In constructor ‘Edge::Edge(ll, cost_type)’:
Main.cpp:44:15: warning: ‘Edge::cost’ will be initialized after [-Wreorder]
   44 |     cost_type cost;
      |               ^~~~
Main.cpp:43:9: warning:   ‘ll Edge::from’ [-Wreorder]
   43 |     int from, to;
      |         ^~~~
Main.cpp:46:5: warning:   when initialized here [-Wreorder]
   46 |     Edge(int to, cost_type cost) : to(to), cost(cost), from(-1) {}
      |     ^~~~
Main.cpp: In function ‘bit_function::i64 bit_function::erase(i64, ll, ll)’:
Main.cpp:196:61: warning: suggest parentheses around arithmetic in operand of ‘|’ [-Wparentheses]
  196 |     i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット
      |                                                           ~~^~~~~~~~~~~~~~~~~~
Main.cpp: In function ‘std::istream& util_function::operator>>(std::istream&, __int128&)’:
Main.cpp:420:27: warning: comparison of integer expressions of different signedness: ‘ll’ {aka ‘long long int’} and ‘std::__cxx11::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  420 |         for (int i = 0; i < S.length(); i++)
      |                         ~~^~~~~~~~~~~~
Main.cpp: In function ‘__int128 util_function::sto128(const std::string&)’:
Main.cpp:444:27: warning: comparison of integer expressions of different signedness: ‘ll’ {aka ‘long long int’} and ‘std::__cxx11::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  444 |         for (int i = 0; i < S.length(); i++)
      |                         ~~^~~~~~~~~~~~
Main.cpp: In function ‘mint modpow(const mint&, ll)’:
Main.cpp:681:13: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  681 |     t = t * t;
      |             ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:682:24: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  682 |     if (n & 1) t = t * x;
      |                        ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp: In function ‘void COMinit(ll)’:
Main.cpp:706:25: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  706 |     _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
      |                         ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:706:25: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  706 |     _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
      |                         ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:706:50: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  706 |     _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
      |                                                  ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:706:50: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  706 |     _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
      |                                                  ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:706:63: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  706 |     _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
      |                                                               ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:708:37: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  708 |         _fac[i] = _fac[i-1] * mint(i);
      |                                     ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:709:48: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  709 |         _inv[i] = -_inv[MOD % i] * mint(MOD / i);
      |                                                ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp:710:41: warning: implicitly-declared ‘constexpr Modint<998244353>& Modint<998244353>::operator=(const Modint<998244353>&)’ is deprecated [-Wdeprecated-copy]
  710 |         _finv[i] = _finv[i - 1] * _inv[i];
      |                                         ^
Main.cpp:628:5: note: because ‘Modint<998244353>’ has user-provided ‘Modint<mod>::Modint(const Modint<mod>&) [with long long int mod = 998244353]’
  628 |     Modint(const Modint &r) { val = r.val; }
      |     ^~~~~~
Main.cpp: In function ‘mint FAC(ll)’:
Main.cpp:715:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  715 |     if (N < 0) return 0; return _fac[N];
      |     ^~
Main.cpp:715:26: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  715 |     if (N < 0) return 0; return _fac[N];
      |                          ^~~~~~
Main.cpp: In function ‘mint FACinv(ll)’:
Main.cpp:718:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  718 |     if (N < 0) return 0; return _finv[N];
      |     ^~
Main.cpp:718:26: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  718 |     if (N < 0) return 0; return _finv[N];
      |                          ^~~~~~
Main.cpp: In function ‘mint COM(ll, ll)’:
Main.cpp:721:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  721 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |     ^~
Main.cpp:721:26: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  721 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |                          ^~
Main.cpp: In function ‘mint COMinv(ll, ll)’:
Main.cpp:725:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  725 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |     ^~
Main.cpp:725:26: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  725 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |                          ^~
Main.cpp: In function ‘mint MCOM(const std::vector<long long int>&)’:
Main.cpp:730:23: warning: comparison of integer expressions of different signedness: ‘ll’ {aka ‘long long int’} and ‘std::vector<long long int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  730 |     for (int i = 0; i < V.size(); i++) N += V[i];
      |                     ~~^~~~~~~~~~
Main.cpp:732:23: warning: comparison of integer expressions of different signedness: ‘ll’ {aka ‘long long int’} and ‘std::vector<long long int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  732 |     for (int i = 0; i < V.size(); i++) ret *= _finv[V[i]];
      |                     ~~^~~~~~~~~~
Main.cpp: In function ‘mint PERM(ll, ll)’:
Main.cpp:736:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  736 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |     ^~
Main.cpp:736:26: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
  736 |     if (N < K) return 0; if (N < 0 or K < 0) return 0;
      |                          ^~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 400 / 400
Status
AC × 3
AC × 23
Set Name Test Cases
Sample sample00.txt, sample01.txt, sample02.txt
All sample00.txt, sample01.txt, sample02.txt, testcase00.txt, testcase01.txt, testcase02.txt, testcase03.txt, testcase04.txt, testcase05.txt, testcase06.txt, testcase07.txt, testcase08.txt, testcase09.txt, testcase10.txt, testcase11.txt, testcase12.txt, testcase13.txt, testcase14.txt, testcase15.txt, testcase16.txt, testcase17.txt, testcase18.txt, testcase19.txt
Case Name Status Exec Time Memory
sample00.txt AC 1 ms 3628 KiB
sample01.txt AC 1 ms 3536 KiB
sample02.txt AC 1 ms 3620 KiB
testcase00.txt AC 1 ms 3636 KiB
testcase01.txt AC 38 ms 11052 KiB
testcase02.txt AC 154 ms 35132 KiB
testcase03.txt AC 242 ms 24872 KiB
testcase04.txt AC 337 ms 28424 KiB
testcase05.txt AC 62 ms 11100 KiB
testcase06.txt AC 341 ms 28328 KiB
testcase07.txt AC 247 ms 24244 KiB
testcase08.txt AC 325 ms 28336 KiB
testcase09.txt AC 283 ms 25040 KiB
testcase10.txt AC 330 ms 28448 KiB
testcase11.txt AC 97 ms 14808 KiB
testcase12.txt AC 310 ms 28424 KiB
testcase13.txt AC 156 ms 20316 KiB
testcase14.txt AC 316 ms 28448 KiB
testcase15.txt AC 17 ms 6640 KiB
testcase16.txt AC 306 ms 28460 KiB
testcase17.txt AC 247 ms 25032 KiB
testcase18.txt AC 55 ms 14048 KiB
testcase19.txt AC 35 ms 10512 KiB