数据有问题, 说a是正整数,但是a可以是0 卡了第9个点. 可以试一下
查看原帖
数据有问题, 说a是正整数,但是a可以是0 卡了第9个点. 可以试一下
594040
bigj楼主2023/4/7 20:18
#include <bits/stdc++.h>

using ll = long long;

// assume -mod <= x < 2mod
constexpr int mod = 1000000;
constexpr ll inf = 1e18;

int norm(int x) {
    if (x < 0) { x += mod; }
    if (x >= mod) { x -= mod; }
    return x;
}
template<class T>
T power(T a, ll b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
struct Z {
    int x;
    Z(int x = 0): x(norm(x)) {}
    Z(ll x): x(norm(x% mod)) {}
    int val() const { return x; }
    Z operator-() const { return Z(norm(mod - x)); }
    Z inv() const {
        assert(x != 0);
        return power(*this, mod - 2);
    }
    Z& operator*=(const Z& rhs) {
        x = ll(x) * rhs.x % mod;
        return *this;
    }
    Z& operator+=(const Z& rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z& operator-=(const Z& rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z& operator/=(const Z& rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator*(const Z& lhs, const Z& rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator+(const Z& lhs, const Z& rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator-(const Z& lhs, const Z& rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator/(const Z& lhs, const Z& rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream& operator>>(std::istream& is, Z& a) {
        ll v;
        is >> v;
        a = Z(v);
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, const Z& a) {
        return os << a.val();
    }
};

struct Node {
    Node* ch[2];
    Node* p;
    ll v;
    int size;

    Node(ll v, Node* p = nullptr): ch{ nullptr, nullptr }, p(p), v(v), size(1) {}

    void pull() {
        size = 1;
        if (ch[0] != nullptr) {
            size += ch[0]->size;
        }
        if (ch[1] != nullptr) {
            size += ch[1]->size;
        }
    }

    void rotate() {
        Node* q = p;
        bool x = !pos();
        q->ch[!x] = ch[x];
        if (ch[x] != nullptr) {
            ch[x]->p = q;
        }
        p = q->p;
        if (q->p != nullptr) {
            q->p->ch[q->pos()] = this;
        }
        ch[x] = q;
        q->p = this;
        q->pull();
        pull();
    }

    bool pos() {
        return p->ch[1] == this;
    }

    void splay(Node* g = nullptr) {
        while (p != g) {
            if (p->p != g) {
                if (pos() == p->pos()) {
                    p->rotate();
                }
                else {
                    rotate();
                }
            }
            rotate();
        }
        pull();
    }
} *root[2], * L[2], * R[2];

Node* select(Node* t, int k) {
    if (t->ch[0] != nullptr) {
        if (k < t->ch[0]->size) {
            return select(t->ch[0], k);
        }
        else {
            k -= t->ch[0]->size;
        }
    }
    if (k == 0) {
        return t;
    }
    k--;
    return select(t->ch[1], k);
}

Node* insert(Node*& u, ll v) {
    Node* p = nullptr;
    while (u) {
        p = u;
        u = u->ch[v > u->v];
    }
    u = new Node(v, p);
    if (p) {
        p->ch[v > p->v] = u;
    }
    u->splay();
    return u;
}

Node* findPrev(Node* u, int v) {
    Node* ans = nullptr;
    ll res = -1;
    while (u) {
        if (u->v <= v) {
            if (u->v > res) {
                res = u->v;
                ans = u;
            }
            u = u->ch[1];
        }
        else {
            u = u->ch[0];
        }
    }
    return ans;
}

Node* findNext(Node* u, int v) {
    Node* ans = nullptr;
    ll res = inf + 1;
    while (u) {
        if (u->v >= v) {
            if (u->v < res) {
                res = u->v;
                ans = u;
            }
            u = u->ch[0];
        }
        else {
            u = u->ch[1];
        }
    }
    return ans;
}

Node* Pre(Node* u, int v) {
    Node* ans = nullptr;
    ll res = -1;
    while (u) {
        if (u->v < v) {
            if (u->v > res) {
                res = u->v;
                ans = u;
            }
            u = u->ch[1];
        }
        else {
            u = u->ch[0];
        }
    }
    return ans;
}

Node* Nxt(Node* u, int v) {
    Node* ans = nullptr;
    ll res = inf + 1;
    while (u) {
        if (u->v > v) {
            if (u->v < res) {
                res = u->v;
                ans = u;
            }
            u = u->ch[0];
        }
        else {
            u = u->ch[1];
        }
    }
    return ans;
}

int main() {
    std::cin.tie(0);
    std::ios::sync_with_stdio(0);

    int n;
    std::cin >> n;

    Z ans = 0;

    for (int i : {0, 1}) {
        L[i] = insert(root[i], 0);
        R[i] = insert(root[i], inf);
    }

    for (int i = 0; i < n; i++) {
        int k, v;
        std::cin >> k >> v;
        assert(v > 0);
        if (root[k ^ 1]->size == 2) {
            insert(root[k], v);
        }
        else {
            auto pre = findPrev(root[k ^ 1], v);
            auto nxt = findNext(root[k ^ 1], v);
            if (pre->v == 0) {
                // 从root[k ^ 1] 中 删掉nxt
                ans += std::abs(v - nxt->v);
                auto l = Pre(root[k ^ 1], nxt->v);
                auto r = Nxt(root[k ^ 1], nxt->v);
                if (l == nullptr) {
                    l = L[k ^ 1];
                }
                if (r == nullptr) {
                    r = R[k ^ 1];
                }
                l->splay();
                r->splay(l);
                r->ch[0] = nullptr;
                r->pull();
                l->pull();
                root[k ^ 1] = l;
            }
            else if (nxt->v == inf) {
                // 从root[k ^ 1] 中 删掉pre
                ans += std::abs(v - pre->v);
                auto l = Pre(root[k ^ 1], pre->v);
                auto r = Nxt(root[k ^ 1], pre->v);
                if (l == nullptr) {
                    l = L[k ^ 1];
                }
                if (r == nullptr) {
                    r = R[k ^ 1];
                }
                assert(l);
                assert(r);
                l->splay();
                r->splay(l);
                r->ch[0] = nullptr;
                r->pull();
                l->pull();
                root[k ^ 1] = l;
            }
            else {
                if (v - pre->v > nxt->v - v) {
                    std::swap(pre, nxt);
                }
                // 从root[k ^ 1] 中 删掉pre
                ans += std::abs(v - pre->v);
                auto l = Pre(root[k ^ 1], pre->v);
                auto r = Nxt(root[k ^ 1], pre->v);
                if (l == nullptr) {
                    l = L[k ^ 1];
                }
                if (r == nullptr) {
                    r = R[k ^ 1];
                }
                assert(l);
                assert(r);
                l->splay();
                r->splay(l);
                r->ch[0] = nullptr;
                r->pull();
                l->pull();
                root[k ^ 1] = l;
            }
        }
    }

    std::cout << ans << '\n';

    return 0;
}

如图所示的代码会在第9个点RE

2023/4/7 20:18
加载中...