hdu4585(set)

 src:http://acm.hdu.edu.cn/showproblem.php?pid=4585

用stl解法:

#include <iostream>
#include<stdio.h>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
#include<iomanip>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define Max(a,b) a=max(a,b)
#define Min(a,b) a=min(a,b)
const int inf=0x3f3f3f3f;
#define siz 100005
int n,id,g,a[siz];
map<int,int>mp;
int main()
{
    std::ios::sync_with_stdio(false);
    while(scanf("%d",&n)!=EOF&&n!=0){
        mp.clear();
        memset(a,0,sizeof(a));
        set<int>st;
        st.insert(1000000000);
        mp[1000000000]=1;
        while(n--){
            scanf("%d %d",&id,&g);
            printf("%d ",id);
            set<int>::iterator it=st.lower_bound(g);
            if(it==st.end()){
                it--;
                printf("%d\n",mp[*it]);
            }
            else {
                if(it==st.begin()){
                    printf("%d\n",mp[*it]);
                }
                else{
                    int tmp=*it;
                    if(g-(*(--it))<=tmp-g){
                        printf("%d\n",mp[*it]);
                    }
                    else printf("%d\n",mp[tmp]);
                }
            }
            mp[g]=id;
            st.insert(g);
        }
    }
    return 0;
}

 treap解法:

#include <iostream>
#include<stdio.h>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
#include<iomanip>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define Max(a,b) a=max(a,b)
#define Min(a,b) a=min(a,b)
const int inf=0x3f3f3f3f;
#define siz 100005
int n,id,g;
struct TreapNode
{
    int sz,rnd; //rnd即随机优先级
    int g,id; //存储的内容
    TreapNode* child[2];
    TreapNode(int val,int id):g(val),id(id){
        rnd=rand();sz=1;
        child[0]=child[1]=NULL;
    }
    void update(){
        sz=1;
        if(child[0]!=NULL)sz+=child[0]->sz;
        if(child[1]!=NULL)sz+=child[1]->sz;
    }
}*root;
void Remove_tree(TreapNode*&u)
{
    if(u==NULL)return;
    if(u->child[0]!=NULL)Remove_tree(u->child[0]);
    if(u->child[1]!=NULL)Remove_tree(u->child[1]);
    delete(u);
    u=NULL;
}
void Rotate(TreapNode*&u,int type)//d表示旋转方向,0左旋,1右旋
{
    TreapNode*tmp=u->child[type^1];//
    u->child[type^1]=tmp->child[type];
    tmp->child[type]=u;
    u->update();tmp->update();
    u=tmp;
}
void Insert(TreapNode*&u,int g,int id)
{
    if(u==NULL){u=new TreapNode(g,id);}
    else {
        int tmp = g > u->g;
        Insert(u->child[tmp],g,id);
        if(u->child[tmp]->rnd > u->rnd){
            Rotate(u,tmp^1);
        }
    }
    u->update();
}               //注意query千万不要用引用,用指针这东西要万分注意!!!
TreapNode* query(TreapNode*u,int g,int type)//找前驱后继! 没找到返回NULL
{   //type为0找比它小的最大值,为1找比它大的最小值
    TreapNode*pre=NULL;
    while(u!=NULL&&u->g!=g){//寻找值为g的节点
        int d = g > u->g;     //以type为0为例
        if(d == type^1)pre=u;//pre是比u->g小的最大值
        u=u->child[d];
    }     //注意这里一定要有个tmp,不要用u,因为u是treap某节点的别名
    TreapNode*tmp;//相当于指向一个位置的两个门牌号!!!
    tmp=u->child[type];
    if(tmp == NULL)return pre;
    else {
        while(tmp->child[type^1]!=NULL)tmp=tmp->child[type^1];
        return tmp;
    }
}
int calc(TreapNode*&u,int g)
{
    if(u==NULL)return INT_MAX;
    return abs(u->g - g);
}
void print(TreapNode* u)
{
    if(u==NULL)return;
    if(u->child[0]!=NULL)print(u->child[0]);
    printf("%d ",u->g);
    if(u->child[1]!=NULL)print(u->child[1]);
    return;
}

int main()
{
    std::ios::sync_with_stdio(false);
    while(scanf("%d",&n),n!=0){
        Remove_tree(root);
        Insert(root,100000000,1);
        for(int i=1;i<=n;i++){
            int ans;
            scanf("%d %d",&id,&g);
            Insert(root,g,id);
            TreapNode *r0=query(root,g,0);
            TreapNode *r1=query(root,g,1);
            int d0=calc(r0,g),d1=calc(r1,g);
            if(d0<=d1)ans=r0->id;
            else ans=r1->id;
            printf("%d %d\n",id,ans);
        }
    }
    return 0;
}

 

posted @ 2018-07-22 21:46  WindFreedom  阅读(333)  评论(0)    收藏  举报