UVAlive - 4847(简单BST计数)

先建立给定序列的bst

然后定义d[u] 为u所在子树的所有可行性插入顺序

那么d[ u ] = c(sum_node_u - 1 , sum_node_lson)*d[lson]*d[rson];

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
#define rep1(i,x,y) for(int i=x;i<=y;i++)
#define rep(i,n) for(int i=0;i<(int)n;i++)
const int N = 30;
int le[N<],ri[N],head,c[N];
void insert(int u,int v){
    if(u > v){
        if(!le[u]){
            le[u] = v; c[v]=1;
        }
        else insert(le[u],v);
    } else {
        if(!ri[u]){
            ri[u] = v; c[v]=1;
        }
        else insert(ri[u],v);
    }
    c[u]++;
}
const ll mod = 9999991;
ll C[N][N];
void init(){
  C[0][0]=1;
  rep(i,N){
     C[i][0]=C[i][i]=1;
     for(int j=1;j<i;j++)
        C[i][j]=(C[i-1][j] + C[i-1][j-1])%mod;
  }
}
ll d[N];
int dfs(int u){
   if(le[u] || ri[u]){
      d[u] = C[c[le[u]]+c[ri[u]]][c[le[u]]]*(le[u] ? dfs(le[u]) : 1)*(ri[u] ? dfs(ri[u]) : 1)%mod;
      return d[u];
   }
   else return 1;
}
int n;
int main()
{
   init();
   int T;
   scanf("%d",&T);
   while(T--){
      scanf("%d",&n);
      memset(le,0,sizeof(le));
      memset(ri,0,sizeof(ri));
      head = 1;
      rep1(i,1,n){
         int x; scanf("%d",&x);
         if(i==1) {head = x; c[head]=1;}
         else insert(head,x);
      }
      cout<<dfs(head)<<endl;
   }
   return 0;
}


你可能感兴趣的:(UVAlive - 4847(简单BST计数))