BZOJ 2761 不重复数字

Posted on 2016-04-28 23:07  ziliuziliu  阅读(186)  评论(0编辑  收藏  举报

SPLAY查找是否存在就好了。如果不在就插入进去。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 50050
using namespace std;
int tree[maxn][3],v[maxn],t,n,x,tot=0,fath[maxn];
int stack[maxn],cnt=0,root=0;
void reset()
{
    memset(tree,0,sizeof(tree));
    memset(v,0,sizeof(v));
    memset(fath,0,sizeof(fath));
    tot=0;cnt=0;root=0;
}
bool find(int x,int now)
{
    if (now==0) return false;
    if (v[now]>x) return find(x,tree[now][1]);
    else if (v[now]<x) return find(x,tree[now][2]);
    else return true;
}
void insert(int x,int &now,int father)
{
    if (now==0)
    {
        now=++tot;fath[now]=father;v[now]=x;
        return;
    }
    if (x<v[now]) insert(x,tree[now][1],now);
    else insert(x,tree[now][2],now);
}
void rotate(int x,int &k)
{
    int y=fath[x],z=fath[y],l,r;
    if (tree[y][1]==x) l=1;else l=2;
    r=3-l;
    if (y==k) k=x;
    else
    {
        if (tree[z][1]==y) tree[z][1]=x;
        else tree[z][2]=x;
    }
    fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
    tree[y][l]=tree[x][r];tree[x][r]=y;
}
void splay(int x,int &k)
{
    while (x!=k)
    {
        int y=fath[x],z=fath[y];
        if (y!=k)
        {
            if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k);
            else rotate(y,k);
        }
        rotate(x,k);
    }
}
void work()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if (tot==0) {root=1;tot++;v[1]=x;stack[++cnt]=x;}
        if (!find(x,root))
        {
            insert(x,root,root);
            splay(tot,root);
            stack[++cnt]=x;
        }
    }
    for (int i=1;i<=cnt-1;i++)
        printf("%d ",stack[i]);
    printf("%d",stack[cnt]);
    printf("\n");
}
int main()
{
    scanf("%d",&t);
    for (int i=1;i<=t;i++)
    {
        reset();
        work();
    }
    return 0;
}