BZOJ 2761: [JLOI2011]不重复数字

来源:互联网 发布:中文安卓编程开创者 编辑:程序博客网 时间:2024/05/29 06:33

Description

给出N个数,要求把其中重复的去掉,只保留第一次出现的数。
例如,给出的数为1 2 18 3 3 19 2 3 6 5 4,其中2和3有重复,去除后的结果为1 2 18 3 19 6 5 4。

Input

输入第一行为正整数T,表示有T组数据。
接下来每组数据包括两行,第一行为正整数N,表示有N个数。第二行为要去重的N个正整数。

Output

对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。

Sample Input

2

11

1 2 18 3 3 19 2 3 6 5 4

6

1 2 3 4 5 6

Sample Output

1 2 18 3 19 6 5 4

1 2 3 4 5 6

HINT

对于30%的数据,1 <= N <= 100,给出的数不大于100,均为非负整数;

对于50%的数据,1 <= N <= 10000,给出的数不大于10000,均为非负整数;

对于100%的数据,1 <= N <= 50000,给出的数在32位有符号整数范围内。

提示:

由于数据量很大,使用C++的同学请使用scanf和printf来进行输入输出操作,以免浪费不必要的时间。

分析

这题明明可以用哈希或者sort。。但我偏偏就写了平衡树。。

代码

#include <bits/stdc++.h>#define N 50001struct NOTE{    int l,r;    int rand;    int cover;}t[N];int root,size;void rttl(int &k){    int tmp = t[k].r;    t[k].r = t[tmp].l;    t[tmp].l = k;    k = tmp;}void rttr(int &k){    int tmp = t[k].l;    t[k].l = t[tmp].r;    t[tmp].r = k;    k = tmp;}bool flag;void insert(int &x,int k){    if (!x)    {        x = ++size;        t[x].rand = rand();        t[x].cover = k;        return;    }    if (t[x].cover == k)    {        flag = true;        return;    }    if (t[x].cover > k)    {        insert(t[x].l,k);        if (t[t[x].l].rand < t[x].rand)            rttr(x);    }    else    {        insert(t[x].r,k);        if (t[t[x].r].rand < t[x].rand)            rttl(x);    }}int main(){    int T;    scanf("%d",&T);    while (T--)    {        memset(t,0,sizeof(t));        root = size = 0;        int n;        scanf("%d",&n);        for (int i = 1; i <= n; i++)        {            int x;            scanf("%d",&x);            flag = false;            insert(root,x);            if (!flag)                if (i == 1)                    printf("%d",x);                else printf(" %d",x);        }        printf("\n");    }}
0 0