[练习treap]统计数字

【题目描述】

某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

【输入格式】

输入文件包含n+1行:
第1行是整数n,表示自然数的个数。
第2~n+1行每行一个自然数。

【输出格式】

输出文件包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

【样例输入】

8
2
4
2
4
5
100
2
100
【样例输出】

2 3
4 2
5 1
100 2
【分析】

用这个顺便练习了一下treap,还是用不好诶。

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#define MAXN 10010

#define mmm 100000

struct ss {

  int left,right,num,count,weight,size;

} t[MAXN];

int tot,root,n,x;

void modify(int x) {

  t[x].size = t[t[x].left].size + t[t[x].right].size + t[x].count;

}

void left_change(int &x) {

  int te = t[x].left;

  t[x].left = t[te].right;

  t[te].right = x;

  modify(x);

  x = te;

  modify(x);

}

void right_change(int &x) {

  int te = t[x].right;

  t[x].right = t[te].left;

  t[te].left = x;

  modify(x);

  x = te;

  modify(x);

}

void insert(int &x,int y) {

  if (!x) {

    x = ++tot;

    t[x].left = 0;

    t[x].right = 0;

    t[x].size = 1;

    t[x].count = 1;

    t[x].weight = rand()%mmm;

    t[x].num = y;

  } else {

      if (y == t[x].num)

        ++t[x].count;

      else

        if (y < t[x].num) {

          insert(t[x].left,y);

          if (t[t[x].left].weight < t[x].weight)

            left_change(x);

        } else {

            insert(t[x].right,y);

            if (t[t[x].right].weight < t[x].weight)

              right_change(x);

          }

      modify(x);

    }

}

void print(int x) {

  if (t[x].left)

    print(t[x].left);

  printf("%d %d\n",t[x].num,t[x].count);

  if (t[x].right)

    print(t[x].right);

}

int main() {

  srand(time(0));

  scanf("%d",&n);

  for (int i = 1;i <= n;++i) {

    scanf("%d",&x);

    insert(root,x);

  }

  print(root);

  return 0;

}

          


你可能感兴趣的:(数字)