Chinaunix首页 | 论坛 | 博客
  • 博客访问: 182167
  • 博文数量: 48
  • 博客积分: 4060
  • 博客等级: 上校
  • 技术积分: 1080
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-23 23:24
文章分类

全部博文(48)

文章存档

2011年(1)

2010年(8)

2009年(2)

2008年(37)

我的朋友

分类: C/C++

2008-04-20 10:26:36

/*
The Number of the Same BST
求给定一个序列可以建成一个二叉排序树,问有多少种序列构成的树和这个一样
总结点个数n,每个节点为根的节点的个数size[i]
则结果为n!/(size[1]..size[n]).
*/
#include
#include
const int max=20025;

int tree[max],size[max];
int da[10001];
int an;

void insert(int x)
{
	int p,y;
	p=1;y=1;
	//查找
	while(size[p]!=0)
	{
		size[p]++;y=p;
		if(x<=tree[p])
			p=p*2;
		else p=p*2+1;
	}
    tree[p]=x;size[p]=1;
}

int inv(int x) //可以改进扩展欧几里德算法求
{
	int s,i;
	//ax=1 mod 9901;
    s=x;
	for(i=1;i<=9901;i++)
	{
       if(s%9901==1) return i;
	   s+=x;
	}
}

void lookup(int p)
{
	//printf("%d\n",size[p]);
	//求每个的逆 9901
	an=an*inv(size[p]);
	an%=9901;
	if(size[2*p+1]+size[2*p]==0)return;
	if(size[2*p]) lookup(2*p);
	if(size[2*p+1]) lookup(2*p+1);
}

int main()
{
	int i,n;
	while(scanf("%d",&n)&&n)
	{
		for(i=1;i<=n;i++)
		{scanf("%d",&da[i]);}

		memset(size,0,sizeof(size));
		memset(tree,0,sizeof(tree));
		
		tree[1]=da[1];size[1]=1;
	    for(i=2;i<=n;i++)
		insert(da[i]);
        //for(i=1;i<=10;i++)
			//printf("%d ",size[i]);
		//printf("\n");
		an=1;
		lookup(1);
		for(i=2;i<=n;i++)
			an=(an*i)%9901;
		printf("%d\n",an);
	}
}
阅读(1396) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~