51nod 1832 先序遍历与后序遍历【二叉树+高精度】
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的二叉树。
两棵二叉树不同当且仅当对于某个x,x的左儿子编号不同或x的右儿子编号不同。
两棵二叉树不同当且仅当对于某个x,x的左儿子编号不同或x的右儿子编号不同。
Input
第一行一个正整数n(3<=n<=10000),表示二叉树的节点数,节点从1到n标号。
第二行n个整数a[i](1<=a[i]<=n),表示二叉树的先序遍历。
第三行n个整数b[i](1<=b[i]<=n),表示二叉树的后序遍历。
Output
输出一个整数表示有多少种方案。保证至少有1种方案。
Input示例
3
1 2 3
2 3 1
Output示例
1
题解:找出只有一个儿子的节点数,则这种节点的儿子可以放在左子树或右子树即两种选择,然后将每种情况相乘即可,结果太大,再抄个高精度的板子嘛。
//yy:唉,我都快不记得怎么敲二叉树了。。类似的还可以拓展到n叉树,都是一类已知先序遍历和后序遍历求可构造树的方案数。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define CLR(a,b) memset((a),(b),sizeof((a))) 6 using namespace std; 7 typedef long long ll; 8 const int N = 10005; 9 struct BigInt 10 { 11 const static int mod = 10000; 12 const static int DLEN = 4; 13 int a[600],len; 14 BigInt() 15 { 16 memset(a,0,sizeof(a)); 17 len = 1; 18 } 19 BigInt(int v) 20 { 21 memset(a,0,sizeof(a)); 22 len = 0; 23 do 24 { 25 a[len++] = v%mod; 26 v /= mod; 27 }while(v); 28 } 29 BigInt(const char s[]) 30 { 31 memset(a,0,sizeof(a)); 32 int L = strlen(s); 33 len = L/DLEN; 34 if(L%DLEN) len++; 35 int index = 0; 36 for(int i = L-1;i >= 0;i -= DLEN) 37 { 38 int t = 0; 39 int k = i - DLEN + 1; 40 if(k < 0) k = 0; 41 for(int j = k;j <= i;j++) 42 t = t*10 + s[j] - '0'; 43 a[index++] = t; 44 } 45 } 46 BigInt operator +(const BigInt &b)const 47 { 48 BigInt res; 49 res.len = max(len,b.len); 50 for(int i = 0;i <= res.len;i++) 51 res.a[i] = 0; 52 for(int i = 0;i < res.len;i++) 53 { 54 res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0); 55 res.a[i+1] += res.a[i]/mod; 56 res.a[i] %= mod; 57 } 58 if(res.a[res.len] > 0) res.len++; 59 return res; 60 } 61 BigInt operator *(const BigInt &b)const 62 { 63 BigInt res; 64 for(int i = 0; i < len; i++) 65 { 66 int up = 0; 67 for(int j = 0;j < b.len;j++) 68 { 69 int temp = a[i] * b.a[j] + res.a[i+j] + up; 70 res.a[i+j] = temp%mod; 71 up = temp/mod; 72 } 73 if(up != 0) 74 res.a[i + b.len] = up; 75 } 76 res.len = len + b.len; 77 while(res.a[res.len - 1] == 0 &&res.len > 1) 78 res.len--; 79 return res; 80 } 81 void output() 82 { 83 printf("%d",a[len-1]); 84 for(int i = len-2;i >=0 ;i--) 85 printf("%04d",a[i]); 86 printf("\n"); 87 } 88 }; 89 BigInt ans(1); 90 int pre[N], post[N]; 91 int n; 92 void dfs(int l1, int r1, int l2, int r2) { 93 if(l1 > r1) return; 94 if(r1 - l1 == 1) return; 95 l1++; r2--; 96 int num = 0; 97 int p = l2; 98 while(post[p] != pre[l1]) p++; 99 int r11 = l1 + (p - l2 + 1), r22 = p + 1; 100 num++; 101 dfs(l1, r11, l2, r22); 102 if((r1-l1)-(p-l2+1)!=0) { 103 num++; dfs(r11, r1, p+1, r2); 104 } 105 num = num == 1 ? 2 : 1; 106 ans = ans * BigInt(num); 107 } 108 int main() { 109 int i, j; 110 scanf("%d", &n); 111 for(i = 0; i < n; ++i) scanf("%d", &pre[i]); 112 for(i = 0; i < n; ++i) scanf("%d", &post[i]); 113 dfs(0,n,0,n); 114 ans.output(); 115 return 0; 116 }