uva 1264 Binary Search Tree 不一樣的演算法
阿新 • • 發佈:2018-12-14
題目思路:想,從根結點開始每個結點是如何確定下來的,先根節點,他從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; }