现在的位置: 首页 > 综合 > 正文

CF-19D Points (树套树)

2013年10月27日 ⁄ 综合 ⁄ 共 1642字 ⁄ 字号 评论关闭

题意: 给出一个二维平面,要求支持三种操作:插入一个点(x,y),删除一个点,以及查询横坐标比给定x大,纵坐标比给定y大的具有最小横坐标的点,输出它的坐标。如果有多个点具有相同x值,输出在满足要求下y值最小的那个。操作次数20W。

解法: 把所有的点离散化后按照y值排序,那么我们需要的答案就是在满足y的情况下找到最小的满足的x值。那么就使用树状数组来实现对y~正无穷这个区间的查询。

对y轴建树,把每个点插到它的y值对应的位置,用树状数组来维护。然后对于每次的询问点(x0,y0),查询y0+1~正无穷区间,在每个位置二分查找最小x值,最后维护一个最小值即为答案,复杂度n*(lgn)^2.

/* **********************************************
Author      : Nero
Created Time: 2013/9/2 15:13:03
Problem id  : CF-19D
Problem Name: Points
*********************************************** */

#include <stdio.h>
#include <string.h>
#include <set>
#include <algorithm>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(int)(b); i++)
#define clr(a,b) memset(a,b,sizeof(a))
typedef pair<int,int> P;
#define MP make_pair

const int INF = 0x3f3f3f3f;
const int MAXN = 201000;

// 离散化
struct San {
    int a[MAXN], n;
    int size() { return n; }
    void init() { n = 0; }
    void push(int x) { a[n++] = x; }
    void doit() { sort(a,a+n); n = unique(a,a+n) - a; }
    int operator [] (int x) { return lower_bound(a,a+n,x) - a; }
}san;

struct Query {
    char c;
    int x,y;
}q[MAXN];
int n;

// 树状数组套set
set <P> ss[MAXN];
set <P> :: iterator it;
inline void add(int p, P node) { for( ; p > 0; p -= p&-p) ss[p].insert(node); }
inline void remove(int p, P node) { for( ; p > 0; p -= p&-p) ss[p].erase(node); }
inline void query(int p, P node) {
    P ans = MP(INF,INF);
    for( ; p < san.size(); p += p&-p) {
        it = ss[p].lower_bound(node);
        if(it == ss[p].end()) continue;
        ans = min(ans, *it);
    }
    if(ans.first == INF) printf("-1\n");
    else printf("%d %d\n", ans.first, ans.second);
}

int main() {
    scanf("%d", &n);
    char s[10];
    for(int i = 0; i < n ; i ++) {
        scanf("%s%d%d", s, &q[i].x, &q[i].y);
        q[i].c = s[0];
        san.push(q[i].y);
    }
    san.doit();
    for(int i = 0; i < n; i ++) {
        if(q[i].c == 'a') add(san[q[i].y], MP(q[i].x,q[i].y));
        else if(q[i].c == 'r') remove(san[q[i].y], MP(q[i].x, q[i].y));
        else query(san[q[i].y]+1, MP(q[i].x+1, q[i].y+1));
    }
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.