[练习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;
}
浙公网安备 33010602011771号