Special Christmas Tree |
Time Limit: 4000ms, Special Time Limit:10000ms, Memory Limit:65536KB |
Total submit users: 14, Accepted users: 10 |
Problem 13559 : No special judgement |
Problem description |
Christmas is coming and everyone is building a Christmas tree, and you are no exception. However you are special and you want to build a special one. You decided to build a binary tree and to hang its root from the ceiling. For this problem a binary tree can be defined as a collection of connected nodes. The topmost node is called the root. Every node in the tree might have 0, 1 or 2 other nodes hanging from it, called children. Nodes with no children are called leaves. And every node has exactly 1 parent, except the root has no parent. |
Input |
Your program will be tested on one or more test cases. The first line of the input will be a single integer T (1 ≤ T ≤ 10,000) representing the number of test cases. Followed by T test cases. Each test case will consist of a single line, containing 2 integers separated by a single space H and L (0≤ H ≤ 1,000,000,000) (1 ≤ L ≤ 1,000,000,000) (1≤ L≤ 2 H ) representing the maximum possible height and the number of leaves of the tree, respectively. |
Output |
For each test case print a single line containing “Case n:” (without quotes) where n is the test case number (starting from 1) followed by a single space then the number of nodes in the most special Christmas tree that has exactly L leaves and height at most H . |
Sample Input |
2 3 2 3 3 |
Sample Output |
Case 1: 7 Case 2: 9 |
Problem Source |
ACPC 2014 |
题意:给你一个二叉树最大的高度和叶子节点的数量,让你构建一个二叉树,使节点最多,输出此时的节点。
题解:当每个叶子节点和最大高度一样时,节点最多。画图可以知道:
1-2 H;
3-4 H-1;
5-8 H-2;
9-16 H-3;
17-32 H-4;
33-64 H-5;
...
枚举从2—L,每次翻倍。注意L为1的情况,刚开始时写的时候注意了,然后写着写着就忘了。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 main() 7 { 8 __int64 t,n,s,s1,s2,cas=1,h,l,i,q; 9 scanf("%I64d",&t); 10 while(t--) 11 { 12 scanf("%I64d%I64d",&h,&l); 13 s=1; 14 s2=0; 15 if(l==1) 16 printf("Case %I64d: %I64d ",cas++,h+1); 17 else 18 { 19 for(i=2;i<=l;i=i*2) 20 { 21 if(i==2) 22 s1=(h-s2)*(i-i/2+1); 23 else 24 s1=(h-s2)*(i-i/2); 25 s=s+s1; 26 s2++; 27 } 28 if(l==i/2) //刚好为当前层的尾节点 29 { 30 q=0; 31 } 32 else 33 q=l-i/2; 34 s=s+q*(h-s2); 35 printf("Case %I64d: %I64d ",cas++,s); 36 } 37 } 38 }