codeforces 19D Points

简介: 点击打开cf 19D 思路: 线段树+单点更新 分析: 1 题目的意思是给定一些点和n个操作,这些点都是在原点(0 , 0)的右边,现在给定三种操作    add x y 是把(x , y)这个点加入    remove x y 是把(x , y)这个点删除    find x y 是查找(x , y)点的右边的点满足x' > x && y' > y 并且有x'和y‘尽量的小 2 题目给定的数据是n是2*10^5,但是点的最大值为10^9,所以我们应该要进行点的离散化。

点击打开cf 19D

思路: 线段树+单点更新

分析:

1 题目的意思是给定一些点和n个操作,这些点都是在原点(0 , 0)的右边,现在给定三种操作

   add x y 是把(x , y)这个点加入

   remove x y 是把(x , y)这个点删除

   find x y 是查找(x , y)点的右边的点满足x' > x && y' > y 并且有x'和y‘尽量的小

2 题目给定的数据是n是2*10^5,但是点的最大值为10^9,所以我们应该要进行点的离散化。但是我们只要对x进行离散化即可

3 我们利用set来保存每一个x对应的y的集合,然后我们利用线段树来维护一个x区间的最大的y。

   为什么要用线段树呢?因为我们知道我们只要只要当前区间的最大值就能够判断是否有没有存在这样的点,然后我们利用二分逼近的思想去求出这个x。只要我们求出了x,那么我们就可以利用之前的set来找比y大的y',这一步可以利用set的内置的lower_bound

4 有一点很重要的就是,由于set和map的存储结构不是线性的,因此它们内置了lower_bound和upper_bound,所以我们利用内置,如果使用通用的时间效率及其底下


代码:

/************************************************
 * By: chenguolin                               * 
 * Date: 2013-09-08                             *
 * Address: http://blog.csdn.net/chenguolinblog *
 ************************************************/
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

#define Lson(x) (x<<1)
#define Rson(x) (Lson(x)|1)
#define Mid(x,y) ((x+y)>>1)
#define Sum(x,y) (x+y)

const int MAXN = 200010;

struct Edge{
    int mark;
    int x;
    int y;
};
Edge e[MAXN];

struct Node{
    int left;
    int right;
    int max_y;
};
Node node[4*MAXN];

int n , m;
int num[MAXN];
set<int>s[MAXN];

void input(){
    m = 1;
    char str[10];
    for(int i = 1 ; i <= n ; i++){
        scanf("%s%d%d" , str , &e[i].x , &e[i].y);
        if(str[0] == 'a')
            e[i].mark = 1;
        else if(str[0] == 'r')
            e[i].mark = 2;
        else
            e[i].mark = 3;
        s[m].clear();
        num[m++] = e[i].x;
    }
}

inline void push_up(int pos){
    node[pos].max_y = max(node[Lson(pos)].max_y , node[Rson(pos)].max_y);
}

void buildTree(int left , int right , int pos){
    node[pos].left = left;
    node[pos].right = right;
    node[pos].max_y = -1;
    if(left == right)
        return;
    int mid = Mid(left , right);
    buildTree(left , mid , Lson(pos));
    buildTree(mid+1 , right , Rson(pos));
}

void update(int x , int pos){
    if(node[pos].left == node[pos].right){
        if(s[x].size())
            node[pos].max_y = *(--s[x].end());
        else
            node[pos].max_y = -1;
        return;
    }
    int mid = Mid(node[pos].left , node[pos].right); 
    if(x <= mid)
        update(x , Lson(pos));
    else
        update(x , Rson(pos));
    push_up(pos);
}

int query(int x , int y , int pos){
    if(node[pos].right <= x)    
        return -1;
    if(node[pos].max_y <= y)
        return -1;
    if(node[pos].left == node[pos].right)
        return node[pos].left;
    int t = query(x , y , Lson(pos)); 
    if(t == -1)
        t = query(x , y , Rson(pos));
    return t;
}

void solve(){
    sort(num+1 , num+1+m); 
    m = unique(num+1 , num+1+m)-(num+1);
    buildTree(1 , m , 1);

    for(int i = 1 ; i <= n ; i++){
        int x = upper_bound(num+1 , num+1+m , e[i].x)-(num+1);
        int y = e[i].y;
        // add
        if(e[i].mark == 1){
            s[x].insert(y);
            update(x , 1);
        }
        // remove
        else if(e[i].mark == 2){
            s[x].erase(y);
            update(x , 1);
        }
        // find
        else{
            int ans = query(x , y , 1);
            if(ans == -1)
                puts("-1");
            else{
                printf("%d %d\n" , num[ans] , *s[ans].upper_bound(y));
            }
        } 
    }
}

int main(){
    while(scanf("%d%*c" , &n) != EOF){
        input();
        solve();
    }
    return 0;
}



 

目录
相关文章
|
7月前
codeforces 289 B. Polo the Penguin and Matrix
题目意思是在n*m的矩阵中,你可以对矩阵中的每个数加或者减d,求最少的操作次数,使得矩阵中所有的元素相同。 虽然在condeforces中被分到了dp一类,但完全可以通过排序,暴力的方法解决。
26 0
|
7月前
Codeforces Round #192 (Div. 2) (330B) B.Road Construction
要将N个城市全部相连,刚开始以为是最小生成树的问题,其实就是一道简单的题目。 要求两个城市之间不超过两条道路,那么所有的城市应该是连在一个点上的,至于这个点就很好找了,只要找到一个没有和其他点有道路限制的即可。
18 0
LeetCode 221. Maximal Square
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
42 0
LeetCode 221. Maximal Square
LeetCode 279. Perfect Squares
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
50 0
LeetCode 279. Perfect Squares
LeetCode 59. Spiral Matrix II
给定正整数n,以螺旋顺序生成填充有从1到n2的元素的方阵。
66 0
|
人工智能
Educational Codeforces Round 33
A. Chess For Three time limit per test1 second memory limit per test256 megabytes inputstanda...
1144 0
|
人工智能
Educational Codeforces Round 31 A B C
A. Book Reading time limit per test2 seconds memory limit per test256 megabytes inputstandard...
1080 0