数据结构刷题

CF19D Points

题目链接

先对 \(x\) 离散化,对每一个 \(x\) 都维护一个 set 表示当前横坐标对应的 \(y\)

每次加入或删除操作就把对应的 set 更新,并且用线段树维护区间 \(x\) 对应的 \(y\) 的最大值,每次加入或删除时更新。

查询操作的时候直接在线段树上二分即可。

时间复杂度 \(\mathcal{O}(n\log n)\)

点击查看代码
#include <bits/stdc++.h>
#define rep(i, j, k) for (int i = (j); i <= (k); i++)
#define per(i, j, k) for (int i = (j); i >= (k); i--)
// #define int long long
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define ALL(a) (a).begin(), (a).end()
#define endl "\n"
int max(int x, int y) { return x > y ? x : y; }
int min(int x, int y) { return x < y ? x : y; }
template <typename T>
void chmax(T &x, int y)
{
    if (y > x)
        x = y;
}
template <typename T>
void chmin(T &x, int y)
{
    if (y < x)
        x = y;
}
using namespace std;
void setIO(string name)
{
    freopen((name + ".in").c_str(), "r", stdin);
    freopen((name + ".out").c_str(), "w", stdout);
}
const int N = 2e5 + 10;
int n, m;
struct Operation
{
    int typ, x, y;
} q[N];
char s[10];
vector<int> vec;
set<int> S[N];
struct SegmentTree
{
    int mx[N << 2];
    void init()
    {
        memset(mx, 0, sizeof(mx));
    }
    void pushup(int x)
    {
        mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
    }
    void update(int x, int l, int r, int p, int v)
    {
        if (l == r)
        {
            mx[x] = v;
            return;
        }
        int mid = (l + r) >> 1;
        if (p <= mid)
            update(x << 1, l, mid, p, v);
        else
            update(x << 1 | 1, mid + 1, r, p, v);
        pushup(x);
    }
    int query(int x, int l, int r, int p, int v)
    {
        if (mx[x] <= v)
        {
            return -1;
        }
        if (l == r)
        {
            return l;
        }
        int mid = (l + r) >> 1, res = -1;
        if (p <= mid)
            res = query(x << 1, l, mid, p, v);
        if (~res)
            return res;
        return query(x << 1 | 1, mid + 1, r, p, v);
    }
} T;
void solve()
{
    cin >> n;
    rep(i, 1, n)
    {
        cin >> s >> q[i].x >> q[i].y;
        if (s[0] == 'a')
            q[i].typ = 0;
        else if (s[0] == 'r')
            q[i].typ = 1;
        else
            q[i].typ = 2;
        vec.push_back(q[i].x);
    }
    sort(ALL(vec));
    vec.resize(unique(ALL(vec)) - vec.begin());
    m = (int)vec.size();
    T.init();
    rep(i, 1, n)
    {
        q[i].x = lower_bound(ALL(vec), q[i].x) - vec.begin() + 1;
        int x = q[i].x, y = q[i].y;
        if (!q[i].typ)
        {
            int ori = (S[x].empty() ? 0 : *S[x].rbegin());
            S[x].insert(y);
            if (y > ori)
            {
                T.update(1, 1, m, x, y);
            }
        }
        else if (q[i].typ == 1)
        {
            int ori = *S[x].rbegin();
            S[x].erase(y);
            if (y == ori)
            {
                T.update(1, 1, m, x, (S[x].empty() ? 0 : *S[x].rbegin()));
            }
        }
        else
        {
            if (x == m)
            {
                cout << "-1\n";
                continue;
            }
            int resx = T.query(1, 1, m, x + 1, y);
            if (resx == -1)
            {
                cout << "-1\n";
                continue;
            }
            int resy = *S[resx].upper_bound(y);
            cout << vec[resx - 1] << " " << resy << endl;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}
posted @ 2023-11-02 22:33  Jerry_Jiang  阅读(30)  评论(0编辑  收藏  举报