Submission #58910736


Source Code Expand

#include <bits/stdc++.h>
using namespace std;
using u64 = uint64_t;
using u128 = __uint128_t;
int lg(int x) { return bit_width<unsigned>(x) - 1; }

const u64 MOD = LLONG_MAX / 4;
u64 add(u64 a, u64 b) {
    a += b;
    if (a >= MOD) a -= MOD;
    return a;
}
u64 mul(u64 a, u64 b) {
    u128 x = (u128)a * (b << 3);
    return add(u64(x >> 64), u64(x) >> 3);
}
struct Affine {
    u64 a, b; // ax + b
    friend Affine operator*(const Affine& L, Affine R) {
        R.b = add(R.b, mul(L.b, R.a));
        R.a = mul(R.a, L.a);
        return R;
    }
    friend auto operator<=>(const Affine&, const Affine&) = default;
};

u64 rnd() {
    static random_device r;
    return (u64(r()) << 32 | r()) % MOD;
}
const u64 base = rnd();
const Affine LEFT = {base, rnd()}, CENTER = {base, rnd()}, RIGHT = {base, rnd()};
const Affine E = {1, 0};

struct SegTree {
    int N;
    vector<Affine> seg;
    SegTree(int N_) : N(N_), seg(2 * N, E) {}
    void set(int i, Affine x) {
        i += N;
        seg[i] = x;
        while (i >>= 1) seg[i] = seg[i << 1] * seg[i << 1 | 1];
    }
    Affine get(int L, int R) {
        Affine resL = E, resR = E;
        for (L += N, R += N; L < R; L >>= 1, R >>= 1) {
            if (L & 1) resL = resL * seg[L++];
            if (R & 1) resR = seg[--R] * resR;
        }
        return resL * resR;
    }
};
int main() {
    cin.tie(0)->sync_with_stdio(0);
    int N;
    cin >> N;
    vector<int> A(N);
    for (int& a : A) cin >> a;

    // Sparse Table (min)
    vector ST(lg(N) + 1, vector<u64>(N));
    for (int i = 0; i < N; i++) ST[0][i] = u64(A[i]) << 32 | i;
    for (int w = 0; w + 1 < size(ST); w++) {
        for (int i = 0; i + (2 << w) <= N; i++) ST[w + 1][i] = min(ST[w][i], ST[w][i + (1 << w)]);
    }
    auto get = [&](int L, int R) {
        assert(0 <= L && L < R && R <= N);
        const int w = lg(R - L);
        const u64 mn = min(ST[w][L], ST[w][R - (1 << w)]);
        return (int)mn;
    };

    // construct Cartesian Tree
    vector<array<int, 3>> tree(N);
    {
        auto dfs = [&](auto dfs, int L, int R) -> void {
            assert(0 <= L && L < R && R <= N);
            static int id = 0;
            const int mid = get(L, R);
            tree[mid][0] = id++;
            if (L < mid) dfs(dfs, L, mid);
            tree[mid][1] = id++;
            if (mid + 1 < R) dfs(dfs, mid + 1, R);
            tree[mid][2] = id;
        };
        dfs(dfs, 0, N);
    }

    // query
    int Q;
    cin >> Q;
    vector queries(Q, pair{0, 0});
    vector hash(Q, array{E, E});
    for (auto& [L, R] : queries) {
        cin >> L >> R;
        L--;
    }

    {
        vector<int> idx(Q);
        iota(begin(idx), end(idx), 0);
        ranges::sort(idx, greater<>{}, [&](int i) { return queries[i].second; });
        SegTree seg(N * 2);
        for (int R = 0; R < N; R++) {
            seg.set(tree[R][0], LEFT);
            seg.set(tree[R][1], CENTER);
            // seg.set(tree[R][2], RIGHT);
            while(size(idx) && queries[idx.back()].second == R + 1) {
                const int i = idx.back();
                idx.pop_back();
                const auto [L, R] = queries[i];
                const int mid = get(L, R);
                auto [l, m, r] = tree[mid];
                hash[i][1] = seg.get(m + 1, r);
            }
        }
    }

    {
        vector<int> idx(Q);
        iota(begin(idx), end(idx), 0);
        ranges::sort(idx, {}, [&](int i) { return queries[i].first; });
        SegTree seg(N * 2);
        for (int L = N; L--; ) {
            seg.set(tree[L][0], LEFT);
            seg.set(tree[L][1], CENTER);
            // seg.set(tree[L][2], RIGHT);
            while(size(idx) && queries[idx.back()].first == L) {
                const int i = idx.back();
                idx.pop_back();
                const auto [L, R] = queries[i];
                const int mid = get(L, R);
                auto [l, m, r] = tree[mid];
                hash[i][0] = seg.get(l + 1, m);
            }
        }
    }
    
    ranges::sort(hash);
    auto [l, r] = ranges::unique(hash);

    cout << (l - begin(hash)) << endl;
}

Submission Info

Submission Time
Task M - Cartesian Trees
User tatyam
Language C++ 23 (gcc 12.2)
Score 100
Code Size 4107 Byte
Status AC
Exec Time 574 ms
Memory 136036 KiB

Compile Error

Main.cpp: In function ‘int main()’:
Main.cpp:63:27: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<long unsigned int>, std::allocator<std::vector<long unsigned int> > >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
   63 |     for (int w = 0; w + 1 < size(ST); w++) {
      |                     ~~~~~~^~~~~~~~~~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 3
AC × 52
Set Name Test Cases
Sample sample-01.txt, sample-02.txt, sample-03.txt
All double_00.txt, double_01.txt, double_02.txt, double_03.txt, double_04.txt, double_05.txt, double_06.txt, double_07.txt, double_08.txt, fractonal_00.txt, fractonal_01.txt, fractonal_02.txt, fractonal_03.txt, fractonal_swap_00.txt, fractonal_swap_01.txt, fractonal_swap_02.txt, fractonal_swap_03.txt, fractonal_swap_04.txt, fractonal_swap_05.txt, fractonal_swap_06.txt, fractonal_swap_07.txt, fractonal_swap_08.txt, line_00.txt, line_01.txt, line_02.txt, line_03.txt, line_04.txt, line_05.txt, random2_00.txt, random2_01.txt, random2_02.txt, random2_03.txt, random2_04.txt, random_00.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, sample-01.txt, sample-02.txt, sample-03.txt
Case Name Status Exec Time Memory
double_00.txt AC 561 ms 110872 KiB
double_01.txt AC 541 ms 110812 KiB
double_02.txt AC 515 ms 110868 KiB
double_03.txt AC 558 ms 110868 KiB
double_04.txt AC 536 ms 110884 KiB
double_05.txt AC 533 ms 110900 KiB
double_06.txt AC 555 ms 110964 KiB
double_07.txt AC 547 ms 110964 KiB
double_08.txt AC 518 ms 110896 KiB
fractonal_00.txt AC 550 ms 108684 KiB
fractonal_01.txt AC 444 ms 77748 KiB
fractonal_02.txt AC 450 ms 79800 KiB
fractonal_03.txt AC 554 ms 110860 KiB
fractonal_swap_00.txt AC 512 ms 103436 KiB
fractonal_swap_01.txt AC 541 ms 110068 KiB
fractonal_swap_02.txt AC 538 ms 108820 KiB
fractonal_swap_03.txt AC 533 ms 107664 KiB
fractonal_swap_04.txt AC 515 ms 105884 KiB
fractonal_swap_05.txt AC 535 ms 110432 KiB
fractonal_swap_06.txt AC 520 ms 105956 KiB
fractonal_swap_07.txt AC 536 ms 104640 KiB
fractonal_swap_08.txt AC 516 ms 104596 KiB
line_00.txt AC 527 ms 135984 KiB
line_01.txt AC 564 ms 136036 KiB
line_02.txt AC 531 ms 136000 KiB
line_03.txt AC 555 ms 135892 KiB
line_04.txt AC 556 ms 135940 KiB
line_05.txt AC 574 ms 136036 KiB
random2_00.txt AC 561 ms 110860 KiB
random2_01.txt AC 558 ms 110816 KiB
random2_02.txt AC 556 ms 110904 KiB
random2_03.txt AC 519 ms 110816 KiB
random2_04.txt AC 508 ms 110880 KiB
random_00.txt AC 1 ms 3452 KiB
random_01.txt AC 1 ms 3432 KiB
random_02.txt AC 1 ms 3496 KiB
random_03.txt AC 1 ms 3636 KiB
random_04.txt AC 1 ms 3440 KiB
random_05.txt AC 2 ms 3756 KiB
random_06.txt AC 7 ms 3880 KiB
random_07.txt AC 33 ms 6788 KiB
random_08.txt AC 178 ms 20600 KiB
random_09.txt AC 192 ms 20632 KiB
random_10.txt AC 206 ms 21336 KiB
random_11.txt AC 222 ms 22788 KiB
random_12.txt AC 251 ms 26284 KiB
random_13.txt AC 287 ms 35328 KiB
random_14.txt AC 382 ms 57492 KiB
random_15.txt AC 563 ms 110956 KiB
sample-01.txt AC 1 ms 3492 KiB
sample-02.txt AC 1 ms 3432 KiB
sample-03.txt AC 1 ms 3528 KiB