• CodeForces 19D Points(线段树+map)


      开始想不通,后来看网上说是set,就有一个想法是对每个x建一个set。。。然后又想直接建立两重的set就好,最后发现不行,自己想多了。。。 
      题意是给你三种操作:add (x y) 平面添加(x y)这个点 
    remove (x y)平面删除(x y)这个点 
    find (x y) 查找(x y)这个点严格的右上方中最左边的点,有多个就再找最下方的点,输出

      其实想通了还是比较简单的,我的想法就是对于x先排序再对y排序,这样建一颗线段树,用处在于:添加和删除都可以当成单点更新,只需要记录最大值就好。find时当用map的upper_bound()找到大于x的位置时,可以直接自顶向下搜到范围内大于当前y值(最大值就在这儿用)得最靠前的位置,因为是排序了的,所以最靠前最小。但是范围太大得离散化,我用的是map离散化,另一个二维map找到当前点是树上的第几个点。 
      注意这儿当没有添加操作时,不能建树,因为这样就会出现 Create(1,0,1)。。。一直爆空间,我还以为map被卡了

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define eps 1E-8
    /*注意可能会有输出-0.000*/
    #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
    #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
    #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
    #define mul(a,b) (a<<b)
    #define dir(a,b) (a>>b)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int ,int > pii;
    const int Inf=1<<28;
    const double Pi=acos(-1.0);
    const int Max=200010;
    const int Max2=200010<<2;
    char str[Max][10];
    int xx1[Max],yy1[Max],nnow;
    map<int,int> mpos;//找到第一个大于需要值的最左边的位置
    map<pii,int> mp;//离散化
    map<pii,int>::iterator it;
    map<int,int>::iterator iit;
    int segtr[Max2],tem[Max2],ans,flag;
    int nmax(int a,int b)
    {
        return a>b?a:b;
    }
    void Upnow(int now,int next)
    {
        segtr[now]=nmax(segtr[next],segtr[next|1]);
        return;
    }
    void Create(int sta,int enn,int now)
    {
        if(sta==enn)
        {
            segtr[now]=-1;
            return;
        }
        int mid=dir(sta+enn,1);
        int next=mul(now,1);
        Create(sta,mid,next);
        Create(mid+1,enn,next|1);
        Upnow(now,next);
        return;
    }
    void Update(int sta,int enn,int now,int x,int y)
    {
        if(sta==enn&&sta==x)
        {
            segtr[now]=y;
           nnow=now;
            return;
        }
        int mid=dir(sta+enn,1);
        int next=mul(now,1);
        if(mid>=x)
            Update(sta,mid,next,x,y);
        else
            Update(mid+1,enn,next|1,x,y);
        Upnow(now,next);
        return;
    }
    void Query(int sta,int enn,int now,int x,int y)//找到范围内大于y的最前面的值(基本可以看做最小值)
    {
        if(sta==enn)
        {
                ans=now;
                flag=0;
                return;
        }
        int mid=dir(sta+enn,1);
        int next=mul(now,1);
        if(flag&&mid>=x&&segtr[next]>y)//这儿判断保证了的效率
            Query(sta,mid,next,x,y);
        if(flag&&segtr[next|1]>y)
            Query(mid+1,enn,next|1,x,y);
        return;
    }
    int main()
    {
        int n,coun;
        while(~scanf("%d",&n))
        {
            nnow=0;
            coun=1;
            mpos.clear();
            mp.clear();
            for(int i=0;i<n;i++)
            {
                scanf("%s %d %d",str[i],&xx1[i],&yy1[i]);
            if(str[i][0] == 'a')
            {
                mp[make_pair(xx1[i],yy1[i])]=0;//二维map
            }
            }
            for(it=mp.begin();it!=mp.end();++it)
            {
                it->second=coun++;//二维map存应该是树上的第几个节点
                if(!mpos.count(it->first.first))
                mpos[it->first.first]=coun-1;
            }
            coun--;
            if(coun)//一定要注意count>0啊
            Create(1,coun,1);
            for(int i=0;i<n;i++)
            {
            if(str[i][0] == 'a')
            {
            Update(1,coun,1,mp[make_pair(xx1[i],yy1[i])],yy1[i]);
            tem[nnow]=xx1[i];
            }
            else if(str[i][0] == 'r')
            {
            Update(1,coun,1,mp[make_pair(xx1[i],yy1[i])],-1);
            tem[nnow]=xx1[i];
            }
            else
            {
            ans=-1;
            flag=1;
            iit=mpos.upper_bound(xx1[i]);
            if(iit==mpos.end())
            {
                printf("-1
    ");
                continue;
            }
            Query(1,coun,1,iit->second,yy1[i]);
            if(ans==-1)
                printf("-1
    ");
            else
                printf("%d %d
    ",tem[ans],segtr[ans]);
            }
            }
        }
        return 0;
    }
  • 相关阅读:
    2. text()方法
    【CS231n】斯坦福大学李飞飞视觉识别课程笔记(十五):神经网络笔记2(下)
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
    我的友情链接
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/5863671.html
Copyright © 2020-2023  润新知