제출 #1355713

#제출 시각아이디문제언어결과실행 시간메모리
1355713bakhtiyarnSegments (IZhO18_segments)C++20
0 / 100
1 ms1012 KiB
// gpt's code
#include <bits/stdc++.h>
using namespace std;

const int MX = 2000000000;
const int N = 200000 + 5;

array<int, 2> id[N];

using U64 = unsigned long long;

static inline U64 key0(int v) { return (0ULL << 31) | (unsigned int)v; }
static inline U64 key1(int v) { return (1ULL << 31) | (unsigned int)v; }

struct TNode {
    U64 key;
    int l, r;
    unsigned int pr;
    int cnt, sz;
};

struct SNode {
    int lef, rig;
    int rt;
};

vector<TNode> tr(1);
vector<SNode> seg(2); // seg[1] is root
int C = 2;

static unsigned int rng_state = 712367821u;
static inline unsigned int rng32() {
    rng_state ^= rng_state << 13;
    rng_state ^= rng_state >> 17;
    rng_state ^= rng_state << 5;
    return rng_state;
}

static inline int getsz(int u) {
    return u ? tr[u].sz : 0;
}

static inline void pull(int u) {
    tr[u].sz = tr[u].cnt + getsz(tr[u].l) + getsz(tr[u].r);
}

int newTreapNode(U64 key) {
    tr.push_back({key, 0, 0, rng32(), 1, 1});
    return (int)tr.size() - 1;
}

void rotateLeft(int &u) {
    int v = tr[u].r;
    tr[u].r = tr[v].l;
    tr[v].l = u;
    pull(u);
    pull(v);
    u = v;
}

void rotateRight(int &u) {
    int v = tr[u].l;
    tr[u].l = tr[v].r;
    tr[v].r = u;
    pull(u);
    pull(v);
    u = v;
}

void insertKey(int &u, U64 key) {
    if (!u) {
        u = newTreapNode(key);
        return;
    }
    if (tr[u].key == key) {
        tr[u].cnt++;
        pull(u);
        return;
    }
    if (key < tr[u].key) {
        insertKey(tr[u].l, key);
        if (tr[tr[u].l].pr > tr[u].pr) rotateRight(u);
    } else {
        insertKey(tr[u].r, key);
        if (tr[tr[u].r].pr > tr[u].pr) rotateLeft(u);
    }
    pull(u);
}

void eraseKey(int &u, U64 key) {
    if (!u) return;

    if (tr[u].key == key) {
        if (tr[u].cnt > 1) {
            tr[u].cnt--;
            pull(u);
            return;
        }
        if (!tr[u].l || !tr[u].r) {
            u = tr[u].l ? tr[u].l : tr[u].r;
            return;
        }
        if (tr[tr[u].l].pr > tr[tr[u].r].pr) {
            rotateRight(u);
            eraseKey(tr[u].r, key);
        } else {
            rotateLeft(u);
            eraseKey(tr[u].l, key);
        }
        if (u) pull(u);
        return;
    }

    if (key < tr[u].key) eraseKey(tr[u].l, key);
    else eraseKey(tr[u].r, key);

    if (u) pull(u);
}

int countLess(int u, U64 key) {
    if (!u) return 0;
    if (key <= tr[u].key) return countLess(tr[u].l, key);
    return getsz(tr[u].l) + tr[u].cnt + countLess(tr[u].r, key);
}

int newSegNode() {
    seg.push_back({0, 0, 0});
    return C++;
}

void update(int u, int l, int r, int x, int v, int t) {
    if (t == 1) {
        insertKey(seg[u].rt, key0(v));
        insertKey(seg[u].rt, key1(v - x + 1));
    } else {
        eraseKey(seg[u].rt, key0(v));
        eraseKey(seg[u].rt, key1(v - x + 1));
    }

    if (l == r) return;

    int m = l + ((r - l) >> 1);
    if (x <= m) {
        if (!seg[u].lef) seg[u].lef = newSegNode();
        update(seg[u].lef, l, m, x, v, t);
    } else {
        if (!seg[u].rig) seg[u].rig = newSegNode();
        update(seg[u].rig, m + 1, r, x, v, t);
    }
}

int get(int u, int l, int r, int x, int y, int v, int t) {
    if (!u || y < l || r < x) return 0;

    if (x <= l && r <= y) {
        if (!t) {
            int totalType0 = countLess(seg[u].rt, key1(0));
            return totalType0 - countLess(seg[u].rt, key0(v));
        } else {
            return getsz(seg[u].rt) - countLess(seg[u].rt, key1(v));
        }
    }

    int m = l + ((r - l) >> 1);
    return get(seg[u].lef, l, m, x, y, v, t) +
           get(seg[u].rig, m + 1, r, x, y, v, t);
}

void add(int l, int r) {
    update(1, 0, MX, l, r, 1);
}

void remove(int l, int r) {
    update(1, 0, MX, l, r, 0);
}

int cnt(int l, int r) {
    if (l < 0) return 0;
    return get(1, 0, MX, 0, l, r, 0);
}

int cnt_sz(int l, int r, int k) {
    if (l > r) return 0;
    return get(1, 0, MX, l, r, k, 1);
}

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int q, t;
    cin >> q >> t;

    int ID = 1;
    int last = 0;

    while (q--) {
        int tip;
        cin >> tip;

        if (tip == 1) {
            int a, b;
            cin >> a >> b;
            int l = a ^ (t * last);
            int r = b ^ (t * last);
            if (l > r) swap(l, r);
            add(l, r);
            id[ID++] = {l, r};
        } else if (tip == 2) {
            int rem;
            cin >> rem;
            int l = id[rem][0];
            int r = id[rem][1];
            remove(l, r);
        } else {
            int a, b, k;
            cin >> a >> b >> k;
            int l = a ^ (t * last);
            int r = b ^ (t * last);
            if (l > r) swap(l, r);

            if (r - l + 1 < k) {
                last = 0;
                cout << 0 << '\n';
                continue;
            }

            last = cnt(l - 1, l + k - 1) + cnt_sz(l, r - k + 1, k);
            cout << last << '\n';
        }
    }
}

int main() {
    solve();
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…