Ultraviolet A Problem 10247 complete tree labeling (full tree label)

Source: Internet
Author: User
Tags dot net
// Complete tree labeling (full tree label) // PC/Ultraviolet IDs: 110605/10247, popularity: C, success rate: average level: 2 // verdict: accepted // submission date: 2011-06-06 // UV Run Time: 0.172 S // copyright (c) 2011, Qiu. Metaphysis # Yeah dot net /// how do I obtain a recursive relationship? T (K, d) indicates the number of K-tree labels with the branch factor K and depth D. Also, // n (K, d) indicates the number of nodes contained in the complete K-Cross Tree with the branch factor K and depth D. According to the definition of a complete K-Cross Tree, // A Full k-Cross Tree with a depth of D contains k Full k-cross numbers with a depth of (d-1, the number of nodes can be expressed as N (K, d-1), K * n (K, d-1) + 1 = N (K, D ). The number of labels for each subtree is // T (K, d-1), then the problem is transformed into the following problem: n (K, d)-1 node, numbered 1-(N (K, d)-1), // is divided into k subsets, each of which has n (K, d-1) nodes, how many partitioning methods are there? Because t (K, d-1) is known as long as the number of Division // method is determined, as long as the subset obtained by each division method is one-to-one matched with each subtree, the elements of each // subset can form a one-to-one ing with the labels in T (K, d-1). If the total number of division methods is X, the relationship is as follows: /// T (K, d) = x * (T (K, d-1) ^ K) (1) //// the number of groups X of the set is equivalent to N (K, d-1) nodes from N (K, d-1) each time, K times in total // The total number of different methods obtained. Set a = (N (K, d)-1), B = N (K, d-1), a = K * B, which has: /// x = C (a, B) * C (a-B, B )*...... * C (A-T * B, B), 0 <= T <= k-1 (2) // you can set (2) according to the number of combinations) formula: // X = (!) /(B !) ^ K) (3) // the final result is: // T (K, d) = (n (K, d)-1 )! /(N (K, d-1 )!) ^ K) * t (K, d-1) // ^ K (4) // It is easy to know that T (K, 0) = 1, n (K, d) = (k ^ (D + 1)-1)/(k-1 ). Then you can further simplify // to: // T (K, d) = (N (K, d)-1 )! /N (K, d-1) ^ K/N (K, D-2) ^ (K ^ 2 )/... /// N (k, 1) ^ (K ^ (d-1) (5) /// we can see that multiplication and division operations involving large numbers are involved. # Include <iostream> # include <vector> # include <iomanip> # include <algorithm> using namespace STD; Class INTEGER {friend ostream & operator <(ostream &, const integer &); Public: INTEGER () {}; // converts an unsigned integer to a large integer. INTEGER (unsigned int A) {if (a = 0) digits. push_back (0); else {While (a) {digits. push_back (a % base); A/= base ;}}};~ INTEGER () {}; integer operator * (const integer &); integer & operator * = (unsigned INT); integer & operator * = (const integer &); integer operator/(integer &); bool is_zero (void) {return digits. empty () ;}; PRIVATE: void zero_justify (void); bool less_equal (integer &, unsigned Int &, integer &); vector <unsigned int> digits; // digits. Static unsigned int const base = 10000; // base number. Static unsigned int const width = 4; // digital width .}; // Reload the output symbol <. Ostream & operator <(ostream & OS, const integer & number) {OS <number. digits [number. digits. size ()-1]; for (INT I = number. digits. size ()-2; I> = 0; I --) OS <SETW (number. width) <setfill ('0') <number. digits [I]; return OS;} // remove the leading 0 produced by the large number operation. Void INTEGER: zero_justify (void) {for (INT I = digits. size ()-1; I> = 1; I --) {If (digits [I] = 0) digits. erase (digits. begin () + I); elsebreak;} integer & INTEGER: Operator * = (const integer & B) {return * This = * This * B ;} // multiply the large number by the unsigned integer. Integer & INTEGER: Operator * = (unsigned int B) {If (B> = base) {* This * = INTEGER (B); return * This ;} unsigned int carry = 0; For (INT I = 0; I <digits. size (); I ++) {digits [I] = digits [I] * B + carry; carry = digits [I]/base; digits [I] % = base;} If (carry) digits. push_back (carry); return * This;} // multiplication. Integer INTEGER: Operator * (const integer & B) {INTEGER C; // pre-allocate sufficient space. C. digits. resize (digits. size () + B. digits. size (); fill (C. digits. begin (), C. digits. end (), 0); // calculates the number of rows and adds them one by one. For (INT I = 0; I <B. digits. size (); I ++) for (Int J = 0; j <digits. size (); j ++) {C. digits [I + J] + = digits [J] * B. digits [I]; C. digits [I + J + 1] + = C. digits [I + J]/base; C. digits [I + J] % = base;} // remove the leading 0. C. zero_justify (); Return C;} // checks whether B * v <= row is true. If yes, true is returned. Otherwise, false is returned. Bool INTEGER: less_equal (integer & B, unsigned Int & V, integer & Row) {// The row is related to this question. digits. size () = B. digits. size () + 1, so it can be used. // If the maximum bit of B * V is greater than Row, you can confirm that B * V> row. Int carry = B. digits [B. digits. size ()-1] * V; If (carry/base)> row. digits [row. digits. size ()-1]) return false; // compare by bit. When two digits are not equal, record the comparison result, the last comparison result determines the size/relationship between B * V and row. Bool flag = true; carry = 0; For (INT I = 0; I <B. digits. size (); I ++) {int TMP = B. digits [I] * V + carry; carry = tmp/base; TMP % = base; If (row. digits [I]! = TMP) Flag = TMP <row. digits [I];} // The carry must be compared with the highest bit of the row. If (carry! = Row. digits [row. digits. size ()-1]) Flag = carry <row. digits [row. digits. size ()-1]; return flag;} // division. Use the bipartite method to obtain the operator. Integer INTEGER: Operator/(integer & B) {INTEGER C; integer row; // you need to allocate storage space for the quotient C and the row indicating the row to be reduced. C. digits. resize (digits. size ()-B. digits. size () + 1); row. digits. resize (B. digits. size () + 1); // initialization value. Fill (C. digits. begin (), C. digits. end (), 0); fill (row. digits. begin (), row. digits. end (), 0); For (INT I = digits. size ()-1; I> = 0; I --) {// obtain the dividend. For (Int J = row. digits. size ()-1; j> 0; j --) Row. digits [J] = row. digits [J-1]; row. digits [0] = digits [I]; // obtain the operator of the corresponding digit through the division of the binary test. Int high = base-1; int low = 0; unsigned int v = (high + low + 1)> 1; while (high> LOW) {If (less_equal (B, v, row) Low = V; elsehigh = V-1; V = (high + low + 1)> 1;} // subtract v B from the row. Int borrow, start = 0; For (; Start <B. digits. Size (); Start ++) {// determines the number of bits. Int T = row. digits [start]-V * B. digits [start]; If (T <0) borrow = (base-1-T)/base; elseborrow = 0; // high minus the number of bits. Row. digits [start + 1]-= borrow; // Add a bid to the low position. T + = base * borrow; row. digits [start] = T % base;} // store the corresponding operator in the result. For (Int J = C. digits. size ()-1; j> 0; j --) C. digits [J] = C. digits [J-1]; C. digits [0] = V;} // clear the leading 0. C. zero_justify (); Return C ;}# define treedeepth 22 // Number of labeling schemes with the branch factor K and depth D. Void cal_tree (vector <int> kD) {// number of the total number of K forks that store branch factors as K and depth as D. Integer tree [treedeepth] [treedeepth]; // number of nodes in which the storage branch factor is K and the depth is D. Unsigned int nodes [treedeepth] [treedeepth]; // calculate the number of nodes in the tree that meets K * D <= 21. And find the maximum number of nodes. Unsigned int max = 0; For (INT I = 0; I <kD. size (); I + = 2) {nodes [KD [I] [0] = 1; for (Int J = 1; j <= KD [I + 1]; j ++) {nodes [KD [I] [J] = nodes [KD [I] [J-1] * KD [I] + 1; if (nodes [KD [I] [J]> MAX) max = nodes [KD [I] [J];} // calculate the factorial from 1 to the number of nodes max-1. Vector <integer> fact (max); fact [0] = INTEGER (1); For (unsigned int I = 1; I <Max; I ++) fact [I] = fact [I-1] * I; // calculate the number of label schemes based on the simplified formula (5. For (INT I = 0; I <kD. size (); I + = 2) {If (tree [KD [I] [KD [I + 1]. is_zero () {// calculate n (K, M) ^ (K ^ (D-M), V = K ^ (D-m ). Unsigned int v = 1; integer T (1); For (INT d = KD [I + 1]; D> 0; d --) {v * = KD [I]; for (int K = 1; k <= V; k ++) T * = nodes [KD [I] [d-1];} tree [KD [I] [KD [I + 1] = fact [nodes [KD [I] [KD [I + 1]-1]/t ;} cout <tree [KD [I] [KD [I + 1] <Endl ;}} int main (INT AC, char * AV []) {int K, d; vector <int> KD; while (CIN> K> d) {kD. push_back (k); kD. push_back (d);} cal_tree (KD); Return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.