제출 #1332307

#제출 시각아이디문제언어결과실행 시간메모리
1332307MisterReaperBitaro, who Leaps through Time (JOI19_timeleap)C++20
100 / 100
326 ms25716 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

constexpr i64 inf = i64(1E18);

#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)

// c = -1 [l, r] goes in [l, r]
// othws: [s, p] goes from p with c+max(0,x-s)
struct node {
    int l;
    int r;
    i64 c;
    node() {}
    node(int l_, int r_, i64 c_ = -1) : l(l_), r(r_), c(c_) {}
};
node unite(const node& lhs, const node& rhs) {
    if (lhs.c == -1 && rhs.c == -1) {
        if (lhs.l >= rhs.r) {
            return node(lhs.l, rhs.r, lhs.l - rhs.r);
        } else if (lhs.r <= rhs.l) {
            return node(lhs.r, rhs.l, 0);
        } else {
            assert(std::max(lhs.l, rhs.l) <= std::min(lhs.r, rhs.r));
            return node(std::max(lhs.l, rhs.l), std::min(lhs.r, rhs.r));
        }
    } else if (lhs.c == -1) {
        if (rhs.l <= lhs.l) {
            return node(lhs.l, rhs.r, rhs.c + lhs.l - rhs.l);
        } else if (rhs.l >= lhs.r) {
            return node(lhs.r, rhs.r, rhs.c);
        } else {
            return rhs;
        }
    } else if (rhs.c == -1) {
        if (lhs.r <= rhs.l) {
            return node(lhs.l, rhs.l, lhs.c);
        } else if (lhs.r >= rhs.r) {
            return node(lhs.l, rhs.r, lhs.c + lhs.r - rhs.r);
        } else {
            return lhs;
        }
    } else {
        return node(lhs.l, rhs.r, lhs.c + rhs.c + std::max(0, lhs.r - rhs.l));
    }
}

int N;
std::vector<node> tree;
std::vector<node> eert;

void build(int v, int l, int r, std::vector<std::array<int, 2>>& G) {
    if (l == r) {
        tree[v] = node(G[l][0] - l, G[l][1] - l - 1);
        eert[v] = node(G[l][0] + l + 1, G[l][1] + l);
        return;
    }
    def;
    build(lv, l, mid, G);
    build(rv, mid + 1, r, G);
    tree[v] = unite(tree[lv], tree[rv]);
    eert[v] = unite(eert[rv], eert[lv]);
}

void modify(int v, int l, int r, int p, std::array<int, 2> gx) {
    if (l == r) {
        tree[v] = node(gx[0] - l, gx[1] - l - 1);
        eert[v] = node(gx[0] + l + 1, gx[1] + l);
        return;
    }
    def;
    if (p <= mid) {
        modify(lv, l, mid, p, gx);
    } else {
        modify(rv, mid + 1, r, p, gx);
    }
    tree[v] = unite(tree[lv], tree[rv]);
    eert[v] = unite(eert[rv], eert[lv]);
}

node get(int v, int l, int r, int ql, int qr) {
    if (ql == l && r == qr) {
        return tree[v];
    }
    def;
    if (qr <= mid) {
        return get(lv, l, mid, ql, qr);
    } else if (mid + 1 <= ql) {
        return get(rv, mid + 1, r, ql, qr);
    } else {
        return unite(get(lv, l, mid, ql, mid),
                     get(rv, mid + 1, r, mid + 1, qr));
    }
}

node teg(int v, int l, int r, int ql, int qr) {
    if (ql == l && r == qr) {
        return eert[v];
    }
    def;
    if (qr <= mid) {
        return teg(lv, l, mid, ql, qr);
    } else if (mid + 1 <= ql) {
        return teg(rv, mid + 1, r, ql, qr);
    } else {
        return unite(teg(rv, mid + 1, r, mid + 1, qr),
                     teg(lv, l, mid, ql, mid));
    }
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int Q;
    std::cin >> N >> Q;

    std::vector<std::array<int, 2>> G(N - 1);
    for (int i = 0; i < N - 1; ++i) {
        std::cin >> G[i][0] >> G[i][1];
    }

    if (N != 1) {
        tree.resize((N - 1) << 1);
        eert.resize((N - 1) << 1);
        build(0, 0, N - 2, G);
    }

    for (int i = 0; i < Q; ++i) {
        int TP;
        std::cin >> TP;
        if (TP == 1) {
            int P, S, T;
            std::cin >> P >> S >> T;
            --P;
            modify(0, 0, N - 2, P, {S, T});
        } else {
            int A, B, C, D;
            std::cin >> A >> B >> C >> D;
            --A, --C;
            if (A == C) {
                std::cout << std::max(0, B - D) << '\n';
            } else if (A < C) {
                B -= A;
                D -= C;
                node nd = unite(unite(node(B, B), get(0, 0, N - 2, A, C - 1)), node(D, D));
                std::cout << nd.c << '\n';
            } else {
                B += A;
                D += C;
                node nd = unite(unite(node(B, B), teg(0, 0, N - 2, C, A - 1)), node(D, D));
                std::cout << nd.c << '\n';
            }
        }
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...