zoukankan      html  css  js  c++  java
  • Codeforces 19D

    题意:在一个二维平面上 有三种操作

       1.添加一个点

       2.删去一个点

       3.询问严格在(x, y)右上的点 先取最左 然后最低的

    题解:先把x离散化 然后用线段树维护横坐标为x的最大值 同样把每个x开一个set 就可以处理添加和删除操作了

       询问(x, y) 就是在横坐标大于x的区域 求第一个最大值大于y的x 然后我们就可以在x这个set里找第一个大于y的点了

       注意好好写询问 单次是$log$的

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <set>
    using namespace std;
    const int MAXN = 2e5 + 5;
    const int INF = 0x3f3f3f3f;
    int T, cnt;
    char s[25];
    int opt[MAXN], x[MAXN], y[MAXN];
    int b[MAXN];
    set<int> st[MAXN];
    
    int zd[MAXN << 2];
    void pushup(int rt) {
        zd[rt] = max(zd[rt << 1], zd[rt << 1 | 1]);
    }
    
    void update(int k, int v, int l, int r, int rt) {
        if(l == r) {
            zd[rt] = max(zd[rt], v);
            return;
        }
    
        int mid = (l + r) >> 1;
        if(k <= mid) update(k, v, l, mid, rt << 1);
        else update(k, v, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    void change(int k, int v, int l, int r, int rt) {
        if(l == r) {
            zd[rt] = v;
            return;
        }
    
        int mid = (l + r) >> 1;
        if(k <= mid) change(k, v, l, mid, rt << 1);
        else change(k, v, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    int find(int pos, int v, int l, int r, int rt) {
        if(pos > cnt) return 0;
        if(zd[rt] <= v) return 0;
        if(l == r) return l;
    
        int mid = (l + r) >> 1;
        if(pos > mid) return find(pos, v, mid + 1, r, rt << 1 | 1);
        else {
            int res = 0;
            res = find(pos, v, l, mid, rt << 1);
            if(res < pos) res = find(pos, v, mid + 1, r, rt << 1 | 1);
            return res;
         }
    }
    
    
    int main() {
        scanf("%d", &T);
        for(int i = 1; i <= T; i++) {
            scanf("%s", s + 1);
            if(s[1] == 'a') opt[i] = 1;
            else if(s[1] == 'r') opt[i] = 2;
            else opt[i] = 3;
            scanf("%d%d", &x[i], &y[i]);
            b[++cnt] = x[i];
        }
        sort(b + 1, b + 1 + cnt);
        cnt = unique(b + 1, b + 1 + cnt) - (b + 1);
    
        for(int i = 1; i <= T; i++) {
            int t = lower_bound(b + 1, b + 1 + cnt, x[i]) - b;
            
            if(opt[i] == 1) {
                st[t].insert(y[i]);
                update(t, y[i], 1, cnt, 1);
            } else if(opt[i] == 2) {
                set<int>::iterator it;
                it = st[t].lower_bound(y[i]);
                st[t].erase(*it);
                if(!st[t].size()) change(t, 0, 1, cnt, 1);
                else change(t, *st[t].end(), 1, cnt, 1);
            } else {
                int res = find(t + 1, y[i], 1, cnt, 1);
                if(res == 0) puts("-1");
                else {
                    set<int>::iterator it;
                    it = st[res].upper_bound(y[i]);
                    printf("%d %d
    ", b[res], *it);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    javaapplicationWeb application setup on Ubuntu VPS
    内容中断随想录(risc cpu的那些事)
    算法线性编程珠玑读书笔记之----->使用线性算法求解连续子序列的最大和
    classnull100
    安装javaUbuntu下安装JDK1.6,并将之设为默认的JDK
    筛选实现C++实现筛选法
    调试设置移动端Web开发环境搭建实践
    路由器交换机[置顶] 路由器和交换机的综合实验⑵
    卡数字怀念的东西:魔方
    密码配置配置SSH免密码登陆
  • 原文地址:https://www.cnblogs.com/lwqq3/p/12804807.html
Copyright © 2011-2022 走看看