제출 #1333775

#제출 시각아이디문제언어결과실행 시간메모리
1333775windowwifeBitaro, who Leaps through Time (JOI19_timeleap)C++20
100 / 100
341 ms46772 KiB
#include <bits/stdc++.h>
#define ll long long
#define task ""
using namespace std;
const int maxn = 3e5 + 2, inf = 1e9 + 7;
ll n, q, L[maxn], R[maxn], tp, a, b, c, d, p, s, e;
struct hihi
{
    bool tp;
    ll l, r, leap;
}st[2][2 * maxn];
struct SegmentTree
{
    hihi merge (hihi A, hihi B)
    {
        hihi C;
        C.leap = A.leap + B.leap;
        int haha = (A.tp << 1) + B.tp;
        if (haha == 0)
        {
            if (max(A.l, B.l) <= min(A.r, B.r))
            {
                C.tp = 0;
                C.l = max(A.l, B.l);
                C.r = min(A.r, B.r);
            }
            else if (A.r < B.l)
            {
                C.tp = 1;
                C.l = A.r;
                C.r = B.l;
            }
            else if (A.l > B.r)
            {
                C.tp = 1;
                C.l = A.l;
                C.r = B.r;
                C.leap += A.l - B.r;
            }
        }
        else if (haha == 1)
        {
            C.tp = 1;
            C.r = B.r;
            if (A.l > B.l)
            {
                C.l = A.l;
                C.leap += A.l - B.l;
            }
            else if (A.r < B.l)
            {
                C.l = A.r;
            }
            else
            {
                C.l = B.l;
            }
        }
        else if (haha == 2)
        {
            C.tp = 1;
            C.l = A.l;
            if (A.r > B.r)
            {
                C.r = B.r;
                C.leap += A.r - B.r;
            }
            else if (A.r < B.l)
            {
                C.r = B.l;
            }
            else
            {
                C.r = A.r;
            }
        }
        else
        {
            C.tp = 1;
            C.l = A.l;
            C.r = B.r;
            C.leap += max(0LL, A.r - B.l);
        }
        return C;
    }
    void build (bool tp, int node, int l, int r)
    {
        if (l == r)
        {
            if (tp == 0)
            {
                st[tp][node].tp = 0;
                st[tp][node].l = L[l] - l;
                st[tp][node].r = R[l] - (l + 1);
                st[tp][node].leap = 0;
            }
            else
            {
                st[tp][node].tp = 0;
                st[tp][node].l = L[n - l] - l;
                st[tp][node].r = R[n - l] - (l + 1);
                st[tp][node].leap = 0;
            }
            return;
        }
        int m = (l + r)/2;
        build(tp, node + 1, l, m);
        build(tp, node + 2 * (m - l + 1), m + 1, r);
        st[tp][node] = merge(st[tp][node + 1], st[tp][node + 2 * (m - l + 1)]);
    }
    void upd (int tp, int node, int l, int r, int idx, int L, int R)
    {
        if (l == r)
        {
            st[tp][node].tp = 0;
            st[tp][node].l = L - l;
            st[tp][node].r = R - (l + 1);
            st[tp][node].leap = 0;
            return;
        }
        int m = (l + r)/2;
        if (idx <= m) upd(tp, node + 1, l, m, idx, L, R);
        else upd(tp, node + 2 * (m - l + 1), m + 1, r, idx, L, R);
        st[tp][node] = merge(st[tp][node + 1], st[tp][node + 2 * (m - l + 1)]);
    }
    hihi get (int tp, int node, int l, int r, int cl, int cr)
    {
        if (cr < l || r < cl) return {0, -inf, inf, 0};
        if (cl <= l && r <= cr) return st[tp][node];
        int m = (l + r)/2;
        return merge(get(tp, node + 1, l, m, cl, cr), get(tp, node + 2 * (m - l + 1), m + 1, r, cl, cr));
    }
}str[2];
int main()
{
    //freopen(task".INP", "r", stdin);
    //freopen(task".OUT", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int i = 1; i < n; i++) cin >> L[i] >> R[i];
    if (n > 1)
    {
        str[0].build(0, 1, 1, n - 1);
        str[1].build(1, 1, 1, n - 1);
    }
    for (int i = 1; i <= q; i++)
    {
        cin >> tp;
        if (tp == 1)
        {
            cin >> p >> s >> e;
            str[0].upd(0, 1, 1, n - 1, p, s, e);
            str[1].upd(1, 1, 1, n - 1, n - p, s, e);
        }
        else
        {
            cin >> a >> b >> c >> d;
            if (a == c) cout << max(0LL, b - d) << '\n';
            else if (a < c)
            {
                b -= a;
                d -= c;
                hihi owo = str[0].get(0, 1, 1, n - 1, a, c - 1);
                ll ans = 0, cur = 0;
                if (owo.tp == 0)
                {
                    if (b < owo.l)
                    {
                        ans += owo.leap;
                        cur = owo.l;
                    }
                    else if (b > owo.r)
                    {
                        ans += owo.leap + b - owo.r;
                        cur = owo.r;
                    }
                    else
                    {
                        ans += owo.leap;
                        cur = b;
                    }
                }
                else
                {
                    cur = owo.r;
                    if (b > owo.l)
                    {
                        ans += owo.leap + b - owo.l;
                    }
                    else
                    {
                        ans += owo.leap;
                    }
                }
                cout << ans + max(0LL, cur - d) << '\n';
            }
            else if (a > c)
            {
                a = n + 1 - a;
                c = n + 1 - c;
                b -= a;
                d -= c;
                hihi owo = str[1].get(1, 1, 1, n - 1, a, c - 1);
                ll ans = 0, cur = 0;
                if (owo.tp == 0)
                {
                    if (b < owo.l)
                    {
                        ans += owo.leap;
                        cur = owo.l;
                    }
                    else if (b > owo.r)
                    {
                        ans += owo.leap + b - owo.r;
                        cur = owo.r;
                    }
                    else
                    {
                        ans += owo.leap;
                        cur = b;
                    }
                }
                else
                {
                    cur = owo.r;
                    if (b > owo.l)
                    {
                        ans += owo.leap + b - owo.l;
                    }
                    else
                    {
                        ans += owo.leap;
                    }
                }
                cout << ans + max(0LL, cur - d) << '\n';
            }
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...