Source: http://poj.org/problem? Id = 1095
Question category: catlan numbers and Recursion
Experience: I learned about catlan.
Time: 2011-7-21
Trees made to order
Time limit:1000 ms |
|
Memory limit:10000 K |
Total submissions:5265 |
|
Accepted:3016 |
Description We can number binary trees using the following scheme: The empty tree is numbered 0. The single-node tree is numbered 1. All binary trees having M nodes have numbers less than all those having m + 1 nodes. Any binary tree having M nodes with left and right Subtrees L and R is numbered N such that all trees having M nodes numbered> N have either left Subtrees numbered higher than l, or a left subtree = L and a right subtree numbered higher than R. The first 10 Binary Trees and tree number 20 in this sequence are shown below: Your job for this problem is to output a binary tree when given its order number. Input Input consists of multiple problem instances. each instance consists of a single integer n, where 1 <=n <= 500,000,000. A value of N = 0 terminates input. (Note that this means you will never have to output the empty tree .) Output For each problem instance, you shocould output one line containing the tree corresponding to the order number for that instance. to print out the tree, use the following scheme: A tree with no children shocould be output as X. A tree with left and right Subtrees L and R shoshould be output as (L') x (R'), where l 'and R' are the representations of L and R. If l is empty, just output X (R '). If R is empty, just output (L') X. Sample Input 1 20 31117532 0 Sample output X ((X)X(X))X (X(X(((X(X))X(X))X(X))))X(((X((X)X((X)X)))X)X) Source East central North America 2001 |
[Submit] [Go Back] [Status] [discuss]
Home page go Back to Top
All rights reserved 2003-2011 Ying fuchen, Xu pengcheng, Xie di
Any problem, please contact Administrator
Question and Analysis
The binary tree numbers follow the following rules. The number of a node is small. The node numbers are the same from the right subtree, and from all to the right subtree, now the question gives you a binary tree number, so that you can output the order of this tree...
Analysis: to do this, you need to know about the catlan number. The number of shapes of Binary Trees on different nodes follows the catlan number. Therefore, we first find out all catlan numbers in the range, and then find the number of nodes for each tree, then, calculate the number of nodes in the left subtree, its value, the number of nodes in the right subtree, and its value, and then recursively solve the problem. The key to this question is to evaluate the value of the left and right subtree-understanding a relationship. When the number of left and right subtree nodes remains unchanged, the left subtree is equivalent to the whole subtree of the right subtree "moving", that is, the catlan number of The number of nodes... So there will be a relationship between division and remainder...
Source code
· /*
·
· #include <iostream>
· #include <cstdio>
· #include <cstring>
· using namespace std;
·
· typedef __int64 llg;
· const int N = 25;
·
· llg n, f[N], sum[N];
·
· void Print(int t, llg n)
· {
· int i, l, r;
· llg tmp;
· for(i = 0; i < t; i++)
· {
· tmp = f[i]*f[t-i-1];
· if(tmp < n) n-= tmp;
· else break;
· }
· l = n/f[t-i-1] + 1;
· if(n%f[t-i-1] == 0) l--;
· r = (n-1)%f[t-i-1] + 1;
· if(i > 0)
· {
· printf("(");
· Print(i, l);
· printf(")");
· }
· printf("X");
· if(t-i-1 > 0)
· {
· printf("(");
· Print(t-i-1, r);
· printf(")");
· }
· }
·
· int main()
· {
· int i, j;
· memset(f, 0, sizeof(f));
· f[0] = f[1] = 1;
· for(i = 2; i < N; i++)
· for(j = 0; j < i; j++)
· f[i] += f[j]*f[i-j-1];
· sum[0] = 0;
· for(i = 1; i < N; i++) sum[i] = sum[i-1] + f[i];
· while(scanf("%I64d", &n))
· {
· if(n == 0) break;
· for(i = 1; i < N; i++)
· if(sum[i] >= n)
· {
· Print(i, n-sum[i-1]);
· printf("\n");
· break;
· }
· }
· return 0;
· }
·
· */
·
·
· #include<iostream>
· using namespace std;
·
· const int N=21;
· __int64 a[N], b[N], n;
·
· void dfs(int num, int th)
· {
· printf("(");
· if(num==1)
· {
· printf("X)");
· return;
· }
·
· int i, tmp = 0;
· for(i=0; i<num; i++)
· {
· tmp += a[i]*a[num-1-i];
· if(tmp>=th)
· break;
· }
· tmp -= a[i]*a[num-1-i];
· th -= tmp;
· int l, r;
· l = 1+th/a[num-1-i];
· if(th%a[num-1-i]==0) l--;
· r = (th-1)%a[num-1-i]+1;
· if(i>0)
· dfs(i, l);
· printf("X");
· if(num-1-i>0)
· dfs(num-1-i, r);
· printf(")");
· }
·
· void d(int num, int th)
· {
· if(num==1)
· {
· printf("X");
· return;
· }
·
· int i, tmp = 0;
· for(i=0; i<num; i++)
· {
· tmp += a[i]*a[num-1-i];
· if(tmp>=th)
· break;
· }
· tmp -= a[i]*a[num-1-i];
· th -= tmp;
· int l, r;
· if(th%a[num-1-i]!=0)
· l = 1+th/a[num-1-i];
· else
· l = th/a[num-1-i];
· r = (th-1)%a[num-1-i]+1;
· if(i>0)
· dfs(i, l);
· printf("X");
· if(num-1-i>0)
· dfs(num-1-i, r);
· }
·
· int main()
· {
· int i, j, k;
· a[0] = 1;
· a[1] = 1;
· b[1] = 1;
· b[0] = 0;
· for(i=2; i<N; i++)
· {
·
· a[i] = (i*4-2)*a[i-1]/(i+1);
· b[i] = a[i]+b[i-1];
· }
· while(scanf("%d", &n)!=EOF)
· {
· if(n==0)
· break;
· for(i=1; i<N; i++)
· {
· if(b[i]>=n)
· break;
· }
· d(i, n-b[i-1]);
· printf("\n");
· }
· return 0;
· }