CodeForces - 19D Points (线段树+set)

博客给出题目链接,介绍解题方法。需离线处理,先离散化,对x坐标建立线段树,维护区间内y坐标最大值,且为每个x坐标建立一个set。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/problemset/problem/19/D

离线,首先要离散化,对x坐标建立线段树,维护区间内y坐标的最大值,每一个x坐标建立一个set

#include <bits/stdc++.h>
#define lson num << 1
#define rson num << 1 | 1
using namespace std;
const int MAXN = 2e5 + 10;
struct node
{
    int l,r,y;
}tree[MAXN << 2];
set<int> st[MAXN];
int x[MAXN],y[MAXN];
int X[MAXN];
char op[MAXN][20];
void pushup(int num)
{
    tree[num].y = max(tree[lson].y,tree[rson].y);
}
void build(int num,int l,int r)
{
    tree[num].l = l;
    tree[num].r = r;
    tree[num].y = -1;
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid + 1,r);
}
void update(int num,int pos)
{
    if(tree[num].l == tree[num].r) {
        if(!st[pos].empty()) tree[num].y = *(--st[pos].end());
        else tree[num].y = -1;
        return;
    }
    int mid = (tree[num].l + tree[num].r) >> 1;
    if(pos <= mid) update(lson,pos);
    else update(rson,pos);
    pushup(num);
}
int query(int num,int qx,int qy)
{
    if(tree[num].r <= qx) return -1;
    if(tree[num].y <= qy) return -1;
    if(tree[num].l == tree[num].r) return tree[num].l;
    int temp = query(lson,qx,qy);
    if(temp == -1) temp = query(rson,qx,qy);
    return temp;
}
int main(void)
{

    int n;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%s %d %d",op[i],&x[i],&y[i]);
        X[i] = x[i];
    }
    sort(X + 1,X + 1 + n);
    int cnt = unique(X + 1,X + 1 + n) - (X + 1);
    build(1,1,cnt);
    for(int i = 1; i <= n; i++) {
        int posx = upper_bound(X + 1,X + 1 + cnt,x[i]) - (X + 1);
        if(op[i][0] == 'a') {
            st[posx].insert(y[i]);
            update(1,posx);
        }
        else if(op[i][0] == 'r') {
            st[posx].erase(y[i]);
            update(1,posx);
        }
        else {
            int ans = query(1,posx,y[i]);
            if(ans == -1) printf("-1\n");
            else printf("%d %d\n",X[ans],*st[ans].upper_bound(y[i]));
        }
    }
    return 0;
}
/*
7
add 1 1
add 3 4
find 0 0
remove 1 1
find 0 0
add 1 1
find 0 0
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值