• CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化


    题目链接:

    http://codeforces.com/contest/19/problem/D

    题意:

    有三种操作“add x y”往平面上添加(x,y)这个点,”remove x y”,将平面上已经存在的点(x,y)删除,“find x y”找出平面上坐标严格大于(x,y)的点,如果有多个点找x最小的,再找y最小的。

    题解:

    所有点 x 坐标离散化,然后按照新的坐标建一个线段树。
    对于每一个坐标x,维护一个set,add操作在相应的set里加入y,remove操作在相应的set里减去y。再有一个mx[]数组来维护最值。每次add、remove操作通过pushup操作更新最值。find操作先在左子树找,如果没找到再跑到右子树,使得x最小。

    代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define MS(a) memset(a,0,sizeof(a))
      5 #define MP make_pair
      6 #define PB push_back
      7 const int INF = 0x3f3f3f3f;
      8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
      9 inline ll read(){
     10     ll x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 //////////////////////////////////////////////////////////////////////////
     16 const int maxn = 210000;
     17 
     18 int n,x[maxn],y[maxn],tmp[maxn];
     19 char op[maxn][8];
     20 
     21 struct node{
     22     int l,r,mx;
     23 }tree[maxn<<2];
     24 
     25 set<int> s[maxn];
     26 
     27 void build(int rt,int l,int r){
     28     tree[rt].l=l,tree[rt].r=r,tree[rt].mx=0;
     29     if(l == r) { s[l].clear(); return ;}
     30     int mid = (l+r)/2;
     31     build(rt<<1,l,mid);
     32     build(rt<<1|1,mid+1,r);
     33 }
     34 
     35 void pushup(int rt){
     36     tree[rt].mx = max(tree[rt<<1].mx, tree[rt<<1|1].mx);
     37 }
     38 
     39 void add(int rt,int pos,int val){
     40     int l = tree[rt].l, r = tree[rt].r;
     41     if(l == r){
     42         s[l].insert(val);
     43         tree[rt].mx = max(tree[rt].mx,val);
     44         return ;
     45     }
     46     int mid = (l+r) / 2;
     47     if(pos <= mid) add(rt<<1,pos,val);
     48     else add(rt<<1|1,pos,val);
     49     pushup(rt);
     50 }
     51 
     52 void move(int rt,int pos,int val){
     53     int l = tree[rt].l,r=tree[rt].r;
     54     if(l == r){
     55         s[l].erase(val);
     56         tree[rt].mx = s[l].empty() ? 0 : *--s[l].end();
     57         return ;
     58     }
     59     int mid = (l+r)/2;
     60     if(pos <= mid) move(rt<<1,pos,val);
     61     else move(rt<<1|1,pos,val);
     62     pushup(rt);
     63 }
     64 
     65 pair<int,int> find(int rt,int pos,int val){
     66     int l=tree[rt].l,r=tree[rt].r;
     67     if(tree[rt].mx<val || r<pos) return make_pair(l,-1);
     68 
     69     if(l == r){
     70         return make_pair(l,*s[l].lower_bound(val));
     71     }
     72     pair<int,int> res = find(rt<<1,pos,val);
     73     if(res.second != -1) return res;
     74     else return find(rt<<1|1,pos,val);
     75 }
     76 
     77 int main(){
     78     cin >> n;
     79     int cnt = 0;
     80     for(int i=0; i<n; i++){
     81         scanf("%s%d%d",op[i],&x[i],&y[i]);
     82         tmp[cnt++] = x[i];
     83     }
     84     sort(tmp,tmp+cnt);
     85     cnt = unique(tmp,tmp+cnt)-tmp;
     86     // for(int i=0; i<cnt; i++)
     87     //  cout << tmp[i] << " ";
     88     // puts("");
     89     build(1,0,cnt-1);
     90 
     91     for(int i=0; i<n; i++){
     92         int pos = lower_bound(tmp,tmp+cnt,x[i])-tmp;
     93         // cout << pos << endl;
     94         if(op[i][0] == 'a') add(1,pos,y[i]);
     95         else if(op[i][0] == 'r') move(1,pos,y[i]);
     96         else {
     97             pair<int,int> ans = find(1,pos+1,y[i]+1);
     98             // cout << pos+1 << endl;
     99             if(ans.second == -1) puts("-1");
    100             else cout << tmp[ans.first] << " " << ans.second << endl;
    101         }
    102     }
    103 
    104     return 0;
    105 }
  • 相关阅读:
    SET NOCOUNT ON 作用
    C# WinForm控件之Dock先后顺序调整
    Sql查询按某字段值排序
    sql server 中DateName()函数及DatePart()函数
    js的字符串代码库及讲解
    js实现字符串格式的日期加一天
    1、用datetimepicker插件实现限定时间范围的选择 2、时间插件实现默认当天的时间和只能选择小于今天的日期
    js判断开始时间不能小于结束时间
    vue监听路由的变化,跳转到同一个页面时,Url改变但视图未重新加载问题
    js对json格式对象进行增加,修改,删除
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827572.html
Copyright © 2020-2023  润新知