uva 1264 Binary Search Tree 不一样的算法

题目链接:https://vjudge.net/problem/UVA-1264

题目思路:想,从根结点开始每个结点是如何确定下来的,先根节点,他从n个位置中选n个出来,他肯定放在第1个,他是C(n,n),接着想根节点的右子树结点,他能放在那些位置,首先先将根节点的左右子树的而所有节点加起来,然后用C选出右结点的个数,也就是C[根结点左子树结点个数+根结点右子树节点个数][根结点右子树结点个数],根节点右子树结点一定是放在C出来的第一个,然后便可以枚举每个是右子树的结点

AC代码

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int tree[5000000];
int num[5000000];
long long C[36][36];
long long maxx;
vector<int>vec;
#define mod 9999991

void insert(int root,int val)
{
    maxx=max(maxx,(long long)root);
    if(tree[root]==0)
    {
        vec.push_back(root);
        tree[root]=val;
        num[root]=1;
        return;
    }
    num[root]++;
    if(val<tree[root])
        insert(root<<1,val);
    else
        insert(root<<1|1,val);
}

int main()
{
    for(int i=0;i<=30;++i)
    {
        for(int j=0;j<=i;++j)
        {
            if(j==0||j==i)
                C[i][j]=1;
            else
                C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
    }
    int t;
    scanf("%d",&t);
    int n;
    while(t--)
    {
        for(int i=0;i<vec.size();++i)
        {
            tree[vec[i]]=0;
            num[vec[i]]=0;
        }
        vec.clear();
        maxx=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            int x;
            scanf("%d",&x);
            insert(1,x);
        }
        long long ans=1;
        for(int i=0;i<vec.size();i++)
        {
            if(vec[i]&1)
                ans=ans*C[num[vec[i]]+num[vec[i]-1]][num[vec[i]]]%mod;//判断是否是右子树结点,如果是,就C[兄弟子树全部结点个数+自己子树全部节点个数][自己子树全部节点个数]
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36921652/article/details/82972728