[BZOJ2761][JLOI2011]不重复数字(splay)

来源:互联网 发布:淘宝moschino 编辑:程序博客网 时间:2024/06/02 07:31

题目描述

传送门

题解

练习平衡树

代码

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 50005int T,n,x,root,sz;bool flag;int f[N],ch[N][2],key[N];void clear(){    flag=false;    root=sz=x=0;    memset(f,0,sizeof(f));memset(ch,0,sizeof(ch));memset(key,0,sizeof(key));}int get(int x){    return ch[f[x]][1]==x;}void rotate(int x){    int old=f[x],oldf=f[old],wh=get(x);    ch[old][wh]=ch[x][wh^1];    f[ch[old][wh]]=old;    ch[x][wh^1]=old;    f[old]=x;    if (oldf) ch[oldf][ch[oldf][1]==old]=x;    f[x]=oldf;}void splay(int x){    for (int fa;fa=f[x];rotate(x))        if (f[fa])            rotate( (get(x)==get(fa))?fa:x );    root=x;}bool insert(int x){    if (!root)    {        root=++sz;        key[sz]=x;        return true;    }    int now=root,fa=0;    while (1)    {        if (x==key[now])        {            splay(now);            return false;        }        fa=now;        now=ch[now][x>key[now]];        if (!now)        {            ++sz;            f[sz]=fa;ch[fa][x>key[fa]]=sz;            key[sz]=x;            splay(sz);            return true;        }    }}int main(){    scanf("%d",&T);    while (T--)    {        clear();        scanf("%d",&n);        for (int i=1;i<=n;++i)        {            scanf("%d",&x);            if (insert(x))            {                if (flag) putchar(' ');                printf("%d",x);                flag=true;            }        }        putchar('\n');    }}
0 0
原创粉丝点击