.CodeforcesBeta Round #19 D. Points 线段树 单点更新

来源:互联网 发布:mysql判断崩溃 编辑:程序博客网 时间:2024/05/16 00:58

题意:三个操作均在二维坐标轴上进行 Add(x,y)加入一个点 remove移出一个点 find寻找最小的坐标严格大于当前点的坐标 没有输出-1 x优先级大于y

题解:因为是在二维坐标轴上操作所以可以将所有操作按照x轴排序,然后把x轴坐标当成线段树的区间,y区间当做线段树权值,线段树记录当前线段最大y值,这样一来query就和常规线段树不太一样

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int N=200010;int flag[N],tree[N<<3];struct point{    int x,y;    bool operator < (const point& a)const{        if(x!=a.x)return x<a.x;        return y<a.y;    }}a[N],x[N],ans,null;void pushup(int rt)//tree记录的是线段树中线段的最大值{    tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);}void update(bool f,int X,int p,int l,int r,int rt)//找到X的位置并更新y的值{    if(l==r){tree[rt]=f?p:-1;return;}    int mid=(l+r)>>1;    if(X<=mid) update(f,X,p,lson);    else update(f,X,p,rson);    pushup(rt);}void query(point p,int l,int r,int rt)//query和常规线段树不太一样{    if(x[r].x<=p.x||tree[rt]<=p.y)return;    if(l==r)ans=x[l];    int mid=(l+r)>>1;    query(p,lson);    if(ans.x==-1)query(p,rson);}int main(){    memset(tree,-1,sizeof(tree));    int n,m=0;    null.x=null.y=-1;    char op[10];    scanf("%d",&n);    for(int i=0;i<n;i++){        scanf("%s%d%d",op,&a[i].x,&a[i].y);        if(op[0]=='a') x[m++]=a[i],flag[i]=1;        else if(op[0]=='f') x[m++]=a[i],flag[i]=2;        else flag[i]=0;    }    sort(x,x+m);    for(int i=0;i<n;i++){        int now=lower_bound(x,x+m,a[i])-x;//找查询的x在x数组中的位置        if(flag[i]<2)update(flag[i],now,a[i].y,0,m-1,1);//更新        else{            ans=null;            query(a[i],0,m-1,1);            if(ans.x==-1) puts("-1");            else printf("%d %d\n",ans.x,ans.y);        }    }    return 0;}


0 0
原创粉丝点击