Submission #74648296


Source Code Expand

//うへうへへうへへへへへ
#include <atcoder/all>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <streambuf>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <memory>
#include <utility>
#include <iterator>
#include <type_traits>
#include <limits>
#include <exception>
#include <stdexcept>
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <stack>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
#include <locale>
#include <clocale>
#include <cctype>
#include <cwctype>
#include <bitset>
#include <array>
#include <forward_list>
#include <random>
#include <numeric>
#include <ratio>
#include <valarray>
#include <tuple>
#include <variant>
#include <optional>
#include <any>
#include <filesystem>
#include <complex>
#include <climits>


using namespace std;
using namespace atcoder;
#define ll long long
#define ld long double
#define rep(i, n) for (int i = 1; i <= (int)(n); i++)
#define rez(i, n) for (int i = 0; i < (int)(n); i++)
#define pb push_back
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define mp make_pair
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define All(A, n) A + 1, A + n + 1
#define Set(A,n) for(int i = 1;i <= n;i++) cin >> A[i]

//条件を満たすか
void YN(bool B) {
    if (B)cout << "Yes" << endl;
    else cout << "No" << endl;
}

//gcd(A, B)
ll GCD(ll a, ll b) {
    while (a % b != 0) {
        ll c = a % b;
        a = b;
        b = c;
    }
    return min(a, b);
}

//lcm(a, b)
ll LCM(ll a, ll b) {
    ll r = GCD(a, b);
    return (a / r) * (b / r);
}

//累乗(a^b % m)
ll Power(ll a, ll b, ll m) {
    ll ret = 1;
    while (b > 0) {
        if (b & 1) (ret *= a) %= m;
        (a *= a) %= m;
        b >>= 1;
    }
    return ret;
}

//a ÷ b(mod m)
ll DivMod(ll a, ll b, ll m) {
    ll inv = Power(b, m - 2, m);
    return (a * inv) % m;
}

//素数判定
bool IsPrime(ll n) {
    if (n <= 1 || (n % 2 == 0 && n > 2)) return false;
    double MX = sqrt(n);
    for (int i = 2; i <= (int)MX; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

//2次方程式の整数解(ない場合は10^18 + 7が返される)
ll Sol2D(ll a, ll b, ll c) {
    // ax^2 + bx + c = 0の解を2分探索
    ll l = 0, r = 1000000000000000007LL;
    while (r - l > 1) {
        ll m = (l + r) / 2;
        if (a * m * m + b * m + c <= 0) l = m;
        else r = m;
    }
    if (a * l * l + b * l + c == 0) return l;
    return 1000000000000000007LL;
}

//最長回文 文字 i を中心とする最長回文の半径
vector<int> manacher(const string& s) {
    vector< int > radius(s.size());
    int i = 0, j = 0;
    while (i < s.size()) {
        while (i - j >= 0 && i + j < s.size() && s[i - j] == s[i + j]) {
            ++j;
        }
        radius[i] = j;
        int k = 1;
        while (i - k >= 0 && i + k < s.size() && k + radius[i - k] < j) {
            radius[i + k] = radius[i - k];
            ++k;
        }
        i += k;
        j -= k;
    }
    return radius;
}

//エラトステネスの篩(n以下のprime(i)が素数のときtrue)
vector< bool > PrimeSieve(int n) {
    vector< bool > prime(n + 1, true);
    if (n >= 0) prime[0] = false;
    if (n >= 1) prime[1] = false;
    for (int i = 2; i * i <= n; i++) {
        if (!prime[i]) continue;
        for (int j = i + i; j <= n; j += i) {
            prime[j] = false;
        }
    }
    return prime;
}

//拡張Euclidの互除法 ax+by=gcd(a,b)となるx, y
template< typename T >
T Extgcd(T a, T b, T& x, T& y) {
    T d = a;
    if (b != 0) {
        d = Extgcd(b, a % b, y, x);
        y -= (a / b) * x;
    }
    else {
        x = 1;
        y = 0;
    }
    return d;
}

//基数変換 a進数のnをb進数に変換
ll Convert_Base(ll a, ll b, ll n) {
    ll value = 0;
    ll power = 1;

    ll tmp = n;
    while (tmp > 0) {
        int digit = tmp % 10;
        tmp /= 10;

        if (digit >= a) return -1;  // 不正な桁

        // オーバーフロー検出
        if (power > LLONG_MAX / a) return -1;
        if (digit != 0 && power > LLONG_MAX / digit) return -1;

        value += digit * power;
        if (value < 0) return -1; // オーバーフロー検出

        power *= a;
    }
    if (value == 0) return 0;

    ll result = 0;
    ll place = 1;

    while (value > 0) {
        int d = value % b;
        value /= b;

        // 桁追加時のオーバーフロー検出
        if (d != 0 && place > LLONG_MAX / d) return -1;
        ll add = d * place;

        if (result > LLONG_MAX - add) return -1; // 加算オーバーフロー
        result += add;

        if (place > LLONG_MAX / 10) return -1;
        place *= 10;
    }

    return result;
}

//二項係数(n_C_kを求める)
ll Comb(ll N, ll K) {
    if (K < 0 || N < K) return 0;
    ll ret = 1;
    for (ll i = 1; i <= K; ++i) {
        ret *= N--;
        ret /= i;
    }
    return ret;
}

//素因数分解(mapで与えられる)
map< ll, ll > Prime_factor(ll n) {
    map< ll, ll > ret;
    for (ll i = 2; i * i <= n; i++) {
        while (n % i == 0) {
            ret[i]++;
            n /= i;
        }
    }
    if (n != 1) ret[n] = 1;
    return ret;
}


//約数列挙

vector<ll> Diver(ll N) {
    vector<ll> L;
    for (ll i = 1; i <= N; i++) {
        if (i * i > N) break;
        if (N % i != 0) continue;
        else {
            if (i * i != N) L.push_back(N / i);
            L.push_back(i);
        }
    }
    sort(L.begin(), L.end());
    return L;
}

// エラトステネスの篩
struct Eratosthenes {
    // テーブル
    vector<bool> isprime;

    // 整数 i を割り切る最小の素数
    vector<int> minfactor;

    // コンストラクタで篩を回す
    Eratosthenes(int N) : isprime(N + 1, true),
        minfactor(N + 1, -1) {
        // 1 は予めふるい落としておく
        isprime[1] = false;
        minfactor[1] = 1;

        // 篩
        for (int p = 2; p <= N; ++p) {
            // すでに合成数であるものはスキップする
            if (!isprime[p]) continue;

            // p についての情報更新
            minfactor[p] = p;

            // p 以外の p の倍数から素数ラベルを剥奪
            for (int q = p * 2; q <= N; q += p) {
                // q は合成数なのでふるい落とす
                isprime[q] = false;

                // q は p で割り切れる旨を更新
                if (minfactor[q] == -1) minfactor[q] = p;
            }
        }
    }

    // 高速素因数分解
    // pair (素因子, 指数) の vector を返す
    vector<pair<int, int>> factorize(int n) {
        vector<pair<int, int>> res;
        while (n > 1) {
            int p = minfactor[n];
            int exp = 0;

            // n で割り切れる限り割る
            while (minfactor[n] == p) {
                n /= p;
                ++exp;
            }
            res.emplace_back(p, exp);
        }
        return res;
    }
};


//BaseImplicitTreap
// T0: 元の配列のモノイド
// T1: T0に対する作用素モノイド
template <class T0, class T1>
class BaseImplicitTreap {
    // T0上の演算、単位元
    virtual T0 f0(T0, T0) = 0;
    const T0 u0;
    // T1上の演算、単位元
    virtual T1 f1(T1, T1) = 0;
    const T1 u1;
    // T0に対するT1の作用
    virtual T0 g(T0, T1) = 0;
    // 多数のt1(T1)に対するf1の合成
    virtual T1 p(T1, int) = 0;

    class xorshift {
        uint64_t x;

    public:
        xorshift() {
            mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
            x = rnd();
            for (int i = 0; i < 100; i++) {
                random();
            }
        }

        uint64_t random() {
            x = x ^ (x << 7);
            return x = x ^ (x >> 9);
        }
    } rnd;

    struct Node {
        T0 value, acc;
        T1 lazy;
        int priority, cnt;
        bool rev;
        Node* l, * r;

        Node(T0 value_, int priority_, T0 u0_, T1 u1_)
            : value(value_), acc(u0_), lazy(u1_), priority(priority_), cnt(1), rev(false), l(nullptr), r(nullptr) {
        }
    } *root = nullptr;

    using Tree = Node*;

    int cnt(Tree t) { return t ? t->cnt : 0; }

    T0 acc(Tree t) { return t ? t->acc : u0; }

    void update_cnt(Tree t) {
        if (t) {
            t->cnt = 1 + cnt(t->l) + cnt(t->r);
        }
    }

    void update_acc(Tree t) {
        if (t) {
            t->acc = f0(acc(t->l), f0(t->value, acc(t->r)));
        }
    }

    void pushup(Tree t) { update_cnt(t), update_acc(t); }

    void pushdown(Tree t) {
        if (t && t->rev) {
            t->rev = false;
            swap(t->l, t->r);
            if (t->l) t->l->rev ^= 1;
            if (t->r) t->r->rev ^= 1;
        }
        if (t && t->lazy != u1) {
            if (t->l) {
                t->l->lazy = f1(t->l->lazy, t->lazy);
                t->l->acc = g(t->l->acc, p(t->lazy, cnt(t->l)));
            }
            if (t->r) {
                t->r->lazy = f1(t->r->lazy, t->lazy);
                t->r->acc = g(t->r->acc, p(t->lazy, cnt(t->r)));
            }
            t->value = g(t->value, p(t->lazy, 1));
            t->lazy = u1;
        }
        pushup(t);
    }

    void split(Tree t, int key, Tree& l, Tree& r) {
        if (!t) {
            l = r = nullptr;
            return;
        }
        pushdown(t);
        int implicit_key = cnt(t->l) + 1;
        if (key < implicit_key) {
            split(t->l, key, l, t->l), r = t;
        }
        else {
            split(t->r, key - implicit_key, t->r, r), l = t;
        }
        pushup(t);
    }

    void insert(Tree& t, int key, Tree item) {
        Tree t1, t2;
        split(t, key, t1, t2);
        merge(t1, t1, item);
        merge(t, t1, t2);
    }

    void merge(Tree& t, Tree l, Tree r) {
        pushdown(l);
        pushdown(r);
        if (!l || !r) {
            t = l ? l : r;
        }
        else if (l->priority > r->priority) {
            merge(l->r, l->r, r), t = l;
        }
        else {
            merge(r->l, l, r->l), t = r;
        }
        pushup(t);
    }

    void erase(Tree& t, int key) {
        Tree t1, t2, t3;
        split(t, key + 1, t1, t2);
        split(t1, key, t1, t3);
        merge(t, t1, t2);
    }

    void update(Tree t, int l, int r, T1 x) {
        if (l >= r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->lazy = f1(t2->lazy, x);
        t2->acc = g(t2->acc, p(x, cnt(t2)));
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    T0 query(Tree t, int l, int r) {
        if (l == r) return u0;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        T0 ret = t2->acc;
        merge(t2, t2, t3);
        merge(t, t1, t2);
        return ret;
    }

    // [l, r)の中で左から何番目か
    int find(Tree t, T0 x, int offset, bool left = true) {
        if (f0(t->acc, x) == x) {
            return -1;
        }
        else {
            if (left) {
                if (t->l && f0(t->l->acc, x) != x) {
                    return find(t->l, x, offset, left);
                }
                else {
                    return (f0(t->value, x) != x) ? offset + cnt(t->l) : find(t->r, x, offset + cnt(t->l) + 1, left);
                }
            }
            else {
                if (t->r && f0(t->r->acc, x) != x) {
                    return find(t->r, x, offset + cnt(t->l) + 1, left);
                }
                else {
                    return (f0(t->value, x) != x) ? offset + cnt(t->l) : find(t->l, x, offset, left);
                }
            }
        }
    }

    void reverse(Tree t, int l, int r) {
        if (l > r) return;
        Tree t1, t2, t3;
        split(t, l, t1, t2);
        split(t2, r - l, t2, t3);
        t2->rev ^= 1;
        merge(t2, t2, t3);
        merge(t, t1, t2);
    }

    // [l, r)の先頭がmになるようにシフトさせる。std::rotateと同じ仕様
    void rotate(Tree t, int l, int m, int r) {
        reverse(t, l, r);
        reverse(t, l, l + r - m);
        reverse(t, l + r - m, r);
    }

    void dump(Tree t) {
        if (!t) return;
        pushdown(t);
        dump(t->l);
        cout << t->value << " ";
        dump(t->r);
    }

public:
    BaseImplicitTreap(T0 u0_, T1 u1_) : u0(u0_), u1(u1_) {}

    void set_by_vector(const vector<T0>& a) {
        for (int i = 0; i < a.size(); i++) {
            insert(i, a[i]);
        }
    }

    int size() { return cnt(root); }

    void insert(int pos, T0 x) { insert(root, pos, new Node(x, rnd.random(), u0, u1)); }

    void update(int l, int r, T1 x) { update(root, l, r, x); }

    T0 query(int l, int r) { return query(root, l, r); }

    // 二分探索。[l, r)内のkでf0(tr[k], x) != xとなる最左/最右のもの。存在しない場合は-1
    // たとえばMinMonoidの場合、x未満の最左/最右の要素の位置を返す
    int binary_search(int l, int r, T0 x, bool left = true) {
        if (l >= r) return -1;
        Tree t1, t2, t3;
        split(root, l, t1, t2);
        split(t2, r - l, t2, t3);
        int ret = find(t2, x, l, left);
        merge(t2, t2, t3);
        merge(root, t1, t2);
        return ret;
    }

    void erase(int pos) { erase(root, pos); }

    void reverse(int l, int r) { reverse(root, l, r); }

    void rotate(int l, int m, int r) { rotate(root, l, m, r); }

    void dump() {
        dump(root);
        cout << endl;
    }

    T0 operator[](int pos) { return query(pos, pos + 1); }
};

template <class T0, class T1>
struct MinUpdateQuery : public BaseImplicitTreap<T0, T1> {
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    MinUpdateQuery() : MinUpdateQuery(numeric_limits<T0>::max(), numeric_limits<T1>::min()) {}
    T0 f0(T0 x, T0 y) override { return min(x, y); }
    T1 f1(T1 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
    T0 g(T0 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
    T1 p(T1 x, int len) override { return x; }
};

template <class T0, class T1>
struct SumAddQuery : public BaseImplicitTreap<T0, T1> {
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    SumAddQuery() : SumAddQuery(0, 0) {}
    T0 f0(T0 x, T0 y) override { return x + y; }
    T1 f1(T1 x, T1 y) override { return x + y; }
    T0 g(T0 x, T1 y) override { return x + y; }
    T1 p(T1 x, int len) override { return x * len; }
};

template <class T0, class T1>
struct MinAddQuery : public BaseImplicitTreap<T0, T1> {
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    MinAddQuery() : MinAddQuery(numeric_limits<T0>::max(), 0) {}
    T0 f0(T0 x, T0 y) override { return min(x, y); }
    T1 f1(T1 x, T1 y) override { return x + y; }
    T0 g(T0 x, T1 y) override { return x + y; }
    T1 p(T1 x, int len) override { return x; }
};

template <class T0, class T1>
struct SumUpdateQuery : public BaseImplicitTreap<T0, T1> {
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    SumUpdateQuery() : SumUpdateQuery(0, numeric_limits<T1>::min()) {}
    T0 f0(T0 x, T0 y) override { return x + y; }
    T1 f1(T1 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
    T0 g(T0 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
    T1 p(T1 x, int len) override { return x == numeric_limits<T1>::min() ? numeric_limits<T1>::min() : x * len; }
};

template <class T0>
struct SumAffineQuery : public BaseImplicitTreap<T0, pair<T0, T0>> {
    using T1 = pair<T0, T0>;  // first * x + second
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    SumAffineQuery() : SumAffineQuery(0, { 1, 0 }) {}
    T0 f0(T0 x, T0 y) override { return x + y; }
    T1 f1(T1 x, T1 y) override { return { x.first * y.first, x.second * y.first + y.second }; }
    T0 g(T0 x, T1 y) override { return y.first * x + y.second; }
    T1 p(T1 x, int len) override { return { x.first, x.second * len }; }
    // update(i, j, {a, b}); // [i, j)にax + bを作用
    // update(i, j, {0, a}); // update
    // update(i, j, {1, a}); // 加算
    // update(i, j, {a, 0}); // 倍
};

template <class T>
struct MinmaxAffineQuery : public BaseImplicitTreap<pair<T, T>, pair<T, T>> {
    using T0 = pair<T, T>;  // {min, max}
    using T1 = pair<T, T>;  // first * x + second
    using BaseImplicitTreap<T0, T1>::BaseImplicitTreap;
    MinmaxAffineQuery()
        : MinmaxAffineQuery({ numeric_limits<T>::max(), -numeric_limits<T>::max() }, { 1, 0 }) {
    }  // TODO: _u1を使うとコンパイル通らない原因不明
    T0 f0(T0 x, T0 y) override { return { min(x.first, y.first), max(x.second, y.second) }; }
    T1 f1(T1 x, T1 y) override { return { x.first * y.first, x.second * y.first + y.second }; }
    T0 g(T0 x, T1 y) override {
        T0 ret = { x.first * y.first + y.second, x.second * y.first + y.second };
        if (y.first < 0) swap(ret.first, ret.second);
        return ret;
    }
    T1 p(T1 x, int len) override { return x; }
    // update(i, j, {a, b}); // [i, j)にax + bを作用
    // update(i, j, {0, a}); // update
    // update(i, j, {1, a}); // 加算
    // update(i, j, {a, 0}); // 倍
};



//PrioritySum
template <typename T, bool ascending = true>
struct PrioritySum {
    SumUpdateQuery<T, T> tr;
    MinUpdateQuery<T, T> tr2;
    int cnt = 0;

    void add(T a) {
        int p = tr2.binary_search(0, tr2.size(), a, !ascending);
        if (ascending) {
            tr.insert(p + 1, a);
            tr2.insert(p + 1, a);
        }
        else {
            if (p == -1) {
                tr.insert(tr.size(), a);
                tr2.insert(tr2.size(), a);
            }
            else {
                tr.insert(p, a);
                tr2.insert(p, a);
            }
        }
        cnt++;
    }

    void erase_at(int k) {
        assert(0 <= k && k < cnt);
        tr.erase(k);
        tr2.erase(k);
        cnt--;
    }

    void erase_value(T a) {
        int p = tr2.binary_search(0, tr2.size(), a, !ascending);
        if (ascending) {
            if (p == cnt) p = 0;
            p++;
        }
        else {
            if (p == -1) p = cnt;
            p--;
        }
        assert(0 <= p && p < tr.size() && tr[p] == a);
        erase_at(p);
    }

    int size() const { return cnt; }

    T sum(int k) { return tr.query(0, k); }

    T operator[](int k) { return tr[k]; }

    void dump() { tr.dump(); }
};

//pair_query
namespace std {
    template <typename T0, typename T1>
    class numeric_limits<pair<T0, T1>> {
    public:
        static constexpr pair<T0, T1> min() { return { numeric_limits<T0>::min(), numeric_limits<T1>::min() }; }
        static constexpr pair<T0, T1> max() { return { numeric_limits<T0>::max(), numeric_limits<T1>::max() }; }
    };
}  // namespace std
// ペアの第一要素でソートし、第一要素がxのものとxより左側のものに対し第二要素の累積を返す
template <typename T0, typename T1, bool ascending = true>
struct PairQuery {
    // 累積用。第二要素を管理
    SumUpdateQuery<T1, T1> tr;
    // 順序管理用
    MinUpdateQuery<pair<T0, T1>, pair<T0, T1>> tr2;
    int cnt = 0;

    void add(const pair<T0, T1>& a) {
        int p = tr2.binary_search(0, tr2.size(), a, !ascending);
        if (ascending) {
            tr.insert(p + 1, a.second);
            tr2.insert(p + 1, a);
        }
        else {
            if (p == -1) {
                tr.insert(tr.size(), a.second);
                tr2.insert(tr2.size(), a);
            }
            else {
                tr.insert(p, a.second);
                tr2.insert(p, a);
            }
        }
        cnt++;
    }

    // 第一要素がxのものとxより左側のものに対し第二要素の累積を返す
    T1 query(T0 x) {
        if (ascending) {
            int p = tr2.binary_search(0, tr2.size(), { x, numeric_limits<T1>::max() }, false);
            p++;
            return tr.query(0, p);
        }
        else {
            int p = tr2.binary_search(0, tr2.size(), { x, numeric_limits<T1>::min() });
            if (p == -1) p = cnt;
            return tr.query(0, p);
        }
    }

    void erase_at(int k) {
        assert(0 <= k && k < cnt);
        tr.erase(k);
        tr2.erase(k);
        cnt--;
    }

    void erase_value(const pair<T0, T1>& a) {
        int p = tr2.binary_search(0, tr2.size(), a, !ascending);
        if (ascending) {
            p++;
        }
        else {
            if (p == -1) p = cnt;
            p--;
        }
        assert(0 <= p && p < cnt && tr2[p] == a);
        erase_at(p);
    }

    int size() const { return cnt; }

    T1 sum(int k) { return tr.query(0, k); }

    pair<T0, T1> operator[](int k) { return tr2[k]; }

    void dump() { tr2.dump(); }
};

//ACLibrary
/*
[Fenwick Tree] 計算量 O(logN)
・配列の一点を変更
・区間要素の総和

(使い方)
fenwick_tree<型名> fw(int n)  {長さnの配列(0から)fwを作る。初期値は0}
fw.add(int p, x)  {fwに対して、a[p] += x}
fw.sum(int l, int r) {fwに対して、a[l] + a[i + 1]・・・a[r - 1]を返す}

[Segtree] 計算量 O(logN)
・要素の一点を変更
・区間要素の総積

(使い方)
※opは二項演算
segtree<型名, op, e()> seg(int n)  {長さnの配列segを作る。初期値はe() O(N)}
segtree<型名, op, e()>seg(vector<型名>v) seg(int n)  {長さnの配列segを作る。初期値はvの内容 O(N)}
seg.set(int p, x) {seg[p]にxを代入 O(log N)}
seg.get(int p) {seg[p]を返す O(1)}
S seg.prod(int l, int r) {op(seg[l], ..., seg[r - 1]) に対し行う。l = rならe()が返る O(log N)}
S seg.all_prod() {op(seg[0], ..., seg[n - 1]) を計算。n = 0 のときは e() O(1)}

int seg.max_right<f>(int l), int seg.max_right<F>(int l, F f)
int seg.min_left<f>(int r), int seg.min_left<F>(int r, F f)

[math]
(使い方)
ll pow_mod(ll x, ll n, int m) {x^n mod m}
ll inv_mod(ll x, ll m) {xy =- 1(mod m)となるyのうち、0 <= y < mを満たすもの}

[DSU]
(使い方)
dsu d(int n) {n頂点0辺の無向グラフdを作る O(n)}
d.merge(int a, int b) {辺a, bを足す O(a(n))}
d.same(int a, int b) {a, bが連結か返す O(a(n))} つまりbool
d.leader(int a) {頂点aの属する連結成分の代表元を返す O(a(n))}
int d.size(int a) {頂点aの属する連結成分のサイズを返す O(a(n))}
vector<vector<int>> d.groups() {グラフを連結成分に分け、その情報を返す O(n)}

[MaxFlow]
(使い方)
mf_graph<Cap> graph(int n) {n頂点0辺のグラフを作る。Capはint, ll O(n)}
int graph.add_edge(int from, int to, Cap cap); {fromからtoへ最大容量cap、流量0の辺を追加し、何番目に追加された辺かを返す O(1)}
他いろいろ

[SCC]有効グラフを強連結成分分解
(使い方)
scc_graph graph(int n) {n頂点0辺の有向グラフgraphを作る O(n)}
graph.add_edge(int from, int to) {頂点 from から頂点 to へ有向辺を足す O(1)}
vector<vector<int>> graph.scc() {条件を満たす「頂点リスト」のリストを返すO(n + m)}

*/

//ローカルライブラリ
/*
・条件を満たすか
void YN(bool B)

・gcd(A, B)
  ll GCD(ll a, ll b)

・lcm(a, b)
 ll LCM(ll a, ll b)

・累乗(a^b % m)
 ll Power(ll a, ll b, ll m)

・a ÷ b(mod m)(a, bとmは互いに素)
 ll DivMod(ll a, ll b, ll m)

・素数判定
 bool IsPrime(ll n)

・2次方程式の整数解(ない場合は10^18 + 7が返される)
 ll Sol2D(ll a, ll b, ll c)

・最長回文 文字 i を中心とする最長回文の半径
 vector<int> manacher(const string& s)

・エラトステネスの篩(n以下のprime(i)が素数のときtrue)
 vector< bool > PrimeSieve(int n)

・拡張Euclidの互除法 ax+by=gcd(a,b)となるx, y
 T Extgcd(T a, T b, T& x, T& y)

・基数変換 a進数のnをb進数に変換
 ll Convert_Base(ll a, ll b, ll n)

・二項係数(n_C_kを求める)
 ll Comb(ll N, ll K)

・素因数分解(mapで与えられる)
 map< ll, ll > Prime_factor(ll n)
*/

//メモ
/*
・配列の二分探索で A[R] >= X を満たす最小Rを探すとき 
 R = lower_bound(A + 1, A + size(A) + 1, X) - A;
・小数点以下10桁まで表示
 printf("%.10f\n", value);
・昇順優先度付きキュー(int型)
 priority_queue< int, vector<int>, greater<int> > q;
・昇順優先度付きキュー(pair<int, int>型)
 priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > Q;
  Implicit Treap

  // MinUpdateQuery<long long, long long> treap;
  //MinUpdateQuery
//SumAddQuery
//MinAddQuery
//SumUpdateQuery
//SumAffineQuery
//MinmaxAffineQuery

  //
  https://xuzijian629.hatenablog.com/entry/2019/10/25/234938
 */

struct grid
{
    ll i; ll j;
    bool operator<(const grid& other) const {
        if (i != other.i) return i < other.i;
        return j < other.j;
    }
};
struct edge
{
    ll from; ll to;
    bool operator<(const edge& other) const {
        if (from != other.from) return from < other.from;
        return  to < other.to;
    }
};


//cout << fixed << setprecision(12)

const double pi = 3.1415926535897932384626;


// セグメント木のための二項演算関数 op と、単位元を返す関数 e
ll op(ll a, ll b) {
    return min(a, b);
}
ll e() { return -1; }



ll M, D;

int main() {
    fastio;
    cin >> M >> D;
    if (M == 1 && D == 7) {
        cout << "Yes" << endl;
        return 0;
    }
    if (M == 3 && D == 3) {
        cout << "Yes" << endl;
        return 0;
    }
    if (M == 5 && D == 5) {
        cout << "Yes" << endl;
        return 0;
    }
    if (M == 7 && D == 7) {
        cout << "Yes" << endl;
        return 0;
    }
    if (M == 9 && D == 9) {
        cout << "Yes" << endl;
        return 0;
    }
    cout << "No" << endl;

}

Submission Info

Submission Time
Task A - Gothec
User Lkarei
Language C++23 (GCC 15.2.0)
Score 100
Code Size 27068 Byte
Status AC
Exec Time 1 ms
Memory 3636 KiB

Compile Error

./Main.cpp: In function 'std::vector<int> manacher(const std::string&)':
./Main.cpp:138:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  138 |     while (i < s.size()) {
      |            ~~^~~~~~~~~~
./Main.cpp:139:36: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  139 |         while (i - j >= 0 && i + j < s.size() && s[i - j] == s[i + j]) {
      |                              ~~~~~~^~~~~~~~~~
./Main.cpp:144:36: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  144 |         while (i - k >= 0 && i + k < s.size() && k + radius[i - k] < j) {
      |                              ~~~~~~^~~~~~~~~~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 4
AC × 17
Set Name Test Cases
Sample 00-sample-01.txt, 00-sample-02.txt, 00-sample-03.txt, 00-sample-04.txt
All 00-sample-01.txt, 00-sample-02.txt, 00-sample-03.txt, 00-sample-04.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, 01-10.txt, 01-11.txt, 01-12.txt, 01-13.txt
Case Name Status Exec Time Memory
00-sample-01.txt AC 1 ms 3524 KiB
00-sample-02.txt AC 1 ms 3548 KiB
00-sample-03.txt AC 1 ms 3556 KiB
00-sample-04.txt AC 1 ms 3432 KiB
01-01.txt AC 1 ms 3516 KiB
01-02.txt AC 1 ms 3556 KiB
01-03.txt AC 1 ms 3420 KiB
01-04.txt AC 1 ms 3636 KiB
01-05.txt AC 1 ms 3548 KiB
01-06.txt AC 1 ms 3420 KiB
01-07.txt AC 1 ms 3616 KiB
01-08.txt AC 1 ms 3516 KiB
01-09.txt AC 1 ms 3524 KiB
01-10.txt AC 1 ms 3436 KiB
01-11.txt AC 1 ms 3540 KiB
01-12.txt AC 1 ms 3488 KiB
01-13.txt AC 1 ms 3524 KiB