洛谷 P6325 [COCI2006-2007#4] ISPITI

\(\texttt{Description}\)

洛谷 \(\text{P}6325\)

  • \(n\) 个操作:

    • \(\texttt{D }x\texttt{ }y\):插入一个 \((x,y)\) 的元素(不会有重复的元素)。

    • \(\texttt{P }i\):查询在所有 \(x\ge x_i,y\ge y_i\) 的元素中(不包括本身),\(y\) 最小的元素的编号(输入顺序),若 \(y\) 相同,则输出 \(x\) 最小的。

  • \(1\le n\le 2\times 10^5\)\(1\le x,y\le 2\times 10^9\)

\(\texttt{Solution}\)

先将所有操作离线,对 \(y\) 离散化。用 set 维护每个 \(y\)\(x\) 的情况。考虑先找到最小的 \(y\),再找到对应的 \(x\)

\(\texttt{P}\) 操作分类讨论(设答案为 \(j\)):

  • \(y_j=y_i\),由于不包括本身,需要这种情况下寻找 \(x_j>x_i\) 的最小的 \(j\)。用 setupper_bound 即可。

  • \(y_j>y_i\),此时不难发现答案有单调性,即对于 \(k\)\(y\in[y_i+1,k]\) 有解,则 \(y\in[y_i+1,k+1]\) 有解;反之无解,则 \(y\in [y_i+1,k-1]\) 无解。二分 \(y_j\),判断 \([y_i+1,y_j]\) 中是否有解。具体来讲,若其中最大的 \(x\) 满足 \(x\ge x_i\),则有解,否则无解。再用线段树维护最大的 \(x\) 即可。找到 \(y_j\) 以后,再用 lower_bound 查询 \(x_j\ge x_i\) 最小的 \(j\) 即可。

对于 \(\texttt{D}\) 操作,先在 set 上插入,如果能更新最大值就更新。

时间复杂度为 \(\mathcal{O}(n\log^2n)\),空间复杂度为 \(\mathcal{O}(n)\)

\(\texttt{Code}\)

Submission

$\texttt{Click For Code}$
#include<bits/stdc++.h>
#define N 200005
#define ls x<<1
#define rs x<<1|1
using namespace std;
int n,tot,num,mx[N<<2];
set<int>s;
set<pair<int,int>>Y[N];
map<int,int>mp;
char c;
pair<int,int>stu[N];
struct data{
    int op,x,y;
}p[N];
void modify(int x,int l,int r,int k,int v){
    if(l^r){
        int m=(l+r)>>1;
        if(k<=m){
            modify(ls,l,m,k,v);
        }else{
            modify(rs,m+1,r,k,v);
        }
        mx[x]=max(mx[ls],mx[rs]);
    }else{
        mx[x]=v;
    }
}
bool query(int x,int l,int r,int ql,int qr,int y){
    if(ql<=l&&r<=qr){
        return mx[x]>=y;
    }
    int m=(l+r)>>1;
    bool ret=0;
    if(ql<=m){
        if(query(ls,l,m,ql,qr,y)){
            return 1;
        }
    }
    if(qr>m){
        ret|=query(rs,m+1,r,ql,qr,y);
    }
    return ret;
}
int main(){
    scanf("%d",&n);
    for(int i=1,x,y;i<=n;++i){
        scanf(" %c",&c);
        if(c^'P'){
            scanf("%d%d",&x,&y);
            p[i]={0,x,y};
            stu[++num]=make_pair(x,y);
            s.insert(y);
        }else{
            scanf("%d",&x);
            p[i]={1,stu[x].first,stu[x].second};
        }
    }
    for(int i:s){
        mp[i]=++tot;
    }
    for(int i=1,x,y,j=0;i<=n;++i){
        x=p[i].x;
        y=mp[p[i].y];
        if(p[i].op){
            auto it=Y[y].upper_bound(make_pair(x,1e9));
            if(it!=Y[y].end()){
                printf("%d\n",it->second);
            }else{
                int l=y+1,r=tot,f=0;
                while(l<=r){
                    int m=(l+r)>>1;
                    if(query(1,1,tot,y+1,m,x)){
                        r=(f=m)-1;
                    }else{
                        l=m+1;
                    }
                }
                if(f){
                    printf("%d\n",Y[f].lower_bound(make_pair(x,0))->second);
                }else{
                    puts("NE");
                }
            }
        }else{
            if(!Y[y].size()||x>Y[y].rbegin()->first){
                modify(1,1,tot,y,x);
            }
            Y[y].insert(make_pair(x,++j));
        }
    }
}
posted @ 2023-03-30 20:23  lzyqwq  阅读(35)  评论(0)    收藏  举报