程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> codeforces 19D Points

codeforces 19D Points

編輯:C++入門知識

思路: 線段樹+單點更新 分析: 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;  
}  

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved