[练习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;
}
          

posted @ 2010-10-14 09:14  Sephiroth.L.  阅读(256)  评论(0编辑  收藏  举报