Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71287
  • 博文数量: 41
  • 博客积分: 1475
  • 博客等级: 上尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 22:49
文章分类
文章存档

2012年(8)

2011年(1)

2009年(32)

我的朋友
最近访客

分类: C/C++

2012-03-23 23:06:16

题目: 

思路: (找规律、big integer)
  • 公式推导请参见下图:
代码:

点击(此处)折叠或打开

  1. //
  2. // Author: xfye
  3. // Status: Accept
  4. //

  5. #include <sstream>
  6. #include <iostream>

  7. #include <vector>
  8. #include <cstring>
  9. #include <cstdlib>

  10. using namespace std;

  11. typedef unsigned int uint;
  12. typedef unsigned long long ullong;
  13. typedef long long llong;


  14. class BigInteger
  15. {
  16. public:
  17.     BigInteger();
  18.     BigInteger(int val);
  19.     BigInteger(unsigned int val);
  20.     BigInteger(ullong val);
  21.     BigInteger(const BigInteger& val);
  22.     BigInteger add(const BigInteger& bint, int val) const;
  23.     BigInteger add(const BigInteger& bint, uint val) const;
  24.     BigInteger add(const BigInteger& x, const BigInteger& y) const;
  25.     std::string toStdString() const;
  26.     bool isNegative() const;

  27.     BigInteger& operator +=(int val);
  28.     BigInteger& operator +=(uint val);
  29.     BigInteger& operator +=(const BigInteger& val);
  30.     BigInteger& operator *=(int val);
  31.     BigInteger& operator *=(uint val);
  32.     BigInteger& operator *=(BigInteger& val);
  33.     BigInteger& operator =(int val);
  34.     BigInteger& operator =(unsigned int val);
  35.     BigInteger& operator =(ullong val);
  36.     BigInteger& operator =(const BigInteger& val);
  37.     bool operator !=(int val);
  38.     bool operator ==(int val);

  39.     // for debug only.
  40.     void debug();

  41. private:
  42.     /// Compare the sign with val
  43.     bool compareSign(int val) const;

  44.     /// Compare the sign with val
  45.     bool compareSign(BigInteger& val) const;

  46.     int wordsNeeded(const uint words[], int len) const;
  47.     void canonicalize();

  48.     void doCarry(unsigned int val);

  49.     void assign(int val);
  50.     void assign(uint val);
  51.     void assign(ullong val);
  52.     void assign(const BigInteger& val);

  53.     void alloc(int newSize);

  54.     BigInteger times(const BigInteger& bint, int val) const;
  55.     BigInteger times(const BigInteger& bint, uint val) const;
  56.     BigInteger times(const BigInteger& x, const BigInteger& y) const;

  57.     void expandWords();
  58.     void expandWords(int newSize);
  59.     void format(int radix, std::string& buffer) const;
  60.     ullong longValue() const;

  61.     ullong udiv_qrnnd(ullong N, uint D) const;
  62.     uint divmod_1 (uint quotient[], uint dividend[], int len, uint divisor) const;
  63.     uint mul_1(uint* dest, const uint* x, int len, uint y) const;
  64.     void mul(uint dest[],
  65.              const uint x[], int xlen,
  66.              const uint y[], int ylen) const;
  67.     uint MPN_add_n(uint dest[], const uint x[], const uint y[], int len) const;

  68.     //
  69.     /// All integers are stored in 2's-complement form.
  70.     /// If words == null, the ival is the value of this BigInteger.
  71.     /// Otherwise, the first ival elements of words make the value
  72.     /// of this BigInteger, stored in little-endian order, 2's-complement form.
  73.     ///
  74.     uint *m_words;
  75.     uint m_ival;

  76.     /// The size of words
  77.     int m_sizeOfWords;

  78.     ///
  79.     int m_sign;
  80. };

  81. BigInteger::BigInteger()
  82.     : m_words(NULL),
  83.       m_ival(0),
  84.       m_sizeOfWords(0),
  85.       m_sign(0)
  86. {
  87. }

  88. BigInteger::BigInteger(int val)
  89.     : m_words(NULL),
  90.       m_sizeOfWords(0)
  91. {
  92.     assign(val);
  93. }

  94. BigInteger::BigInteger(unsigned int val)
  95.     : m_words(NULL),
  96.       m_sizeOfWords(0)
  97. {
  98.     assign(val);
  99. }

  100. BigInteger::BigInteger(ullong val)
  101. {
  102.     assign(val);
  103. }

  104. BigInteger::BigInteger(const BigInteger& val)
  105.     : m_words(NULL)
  106. {
  107.     assign(val);
  108. }

  109. void BigInteger::assign(uint val)
  110. {
  111.     if (m_words != NULL) {
  112.         delete[] m_words;
  113.         m_words = NULL;
  114.         m_sizeOfWords = 0;
  115.     }
  116.     m_ival = val;
  117.     if (val == 0) {
  118.         m_sign = 0;
  119.     } else {
  120.         m_sign = 1;
  121.     }
  122. }

  123. void BigInteger::assign(int val)
  124. {
  125.     if (m_words != NULL) {
  126.         delete[] m_words;
  127.         m_words = NULL;
  128.         m_sizeOfWords = 0;
  129.     }
  130.     if (val == 0) {
  131.         m_sign = 0;
  132.         m_ival = 0;
  133.     } else if (val < 0) {
  134.         m_ival = 0 - val;
  135.         m_sign = -1;
  136.     } else { // val > 0
  137.         m_ival = val;
  138.         m_sign = 1;
  139.     }
  140. }

  141. void BigInteger::assign(ullong val)
  142. {
  143.     uint v = (uint) val;
  144.     if ((ullong) v == val) {
  145.         assign(v);
  146.         return;
  147.     }
  148.     if (m_words == NULL) {
  149.         expandWords();
  150.     }
  151.     m_words[0] = v;
  152.     m_words[1] = val >> 32;
  153.     m_ival = 2;
  154.     m_sign = 1;
  155. }

  156. void BigInteger::assign(const BigInteger& val)
  157. {
  158.     if (m_words != NULL) {
  159.         delete[] m_words;
  160.         m_words = NULL;
  161.     }
  162.     if (val.m_words != NULL) {
  163.         m_sizeOfWords = val.m_sizeOfWords;
  164.         m_words = new uint[val.m_sizeOfWords];
  165.         memcpy(m_words, val.m_words, m_sizeOfWords * sizeof(uint));
  166.     }
  167.     m_ival = val.m_ival;
  168.     m_sign = val.m_sign;
  169. }

  170. BigInteger BigInteger::add(const BigInteger& x, const BigInteger& y) const
  171. {
  172.     BigInteger result;

  173.     if (x.m_words == NULL && y.m_words == NULL) {
  174.         result = ((ullong) y.m_ival + (ullong) x.m_ival);
  175.         return result;
  176.     }

  177.     if (x.m_words == NULL) {
  178.         result = add(y, x.m_ival);
  179.         return result;
  180.     }
  181.     if (y.m_words == NULL) {
  182.         result = add(x, y.m_ival);
  183.         return result;
  184.     }

  185.     BigInteger xx = x;
  186.     BigInteger yy = y;
  187.     // Both are big
  188.     if (y.m_ival > x.m_ival)
  189.     { // Swap so x is longer then y.
  190.         xx = y;
  191.         yy = x;
  192.     }
  193.     result.expandWords(xx.m_ival + 1);
  194.     int i = yy.m_ival;
  195.     ullong carry = MPN_add_n(result.m_words, xx.m_words, yy.m_words, i);
  196.     ullong y_ext = yy.m_words[i - 1] < 0 ? 0xffffffffL : 0;
  197.     for (; i < xx.m_ival; i++) {
  198.         carry += ((ullong) xx.m_words[i] & 0xffffffffL) + y_ext;
  199.         result.m_words[i] = (uint) carry;
  200.         carry >>= 32;
  201.     }
  202.     if (xx.m_words[i - 1] < 0) {
  203.         y_ext--;
  204.     }
  205.     result.m_words[i] = (uint) (carry + y_ext);
  206.     /// result.m_ival = i+1;
  207.     result.m_ival = i+1;
  208.     result.canonicalize();
  209.     return result;
  210. }

  211. BigInteger BigInteger::add(const BigInteger& bint, uint val) const
  212. {
  213.     BigInteger result = bint;

  214.     if (result.m_words == NULL) {
  215.         long long sum = (long long) val + (long long) result.m_ival;
  216.         uint v = (uint) sum;
  217.         if ((long long) v != sum) {
  218.             result.m_words = new uint[32];
  219.             result.m_sizeOfWords = 32;
  220.             result.m_ival = 2;
  221.             result.m_words[0] = v;
  222.             result.m_words[1] = sum >> 32;
  223.         } else {
  224.             result.m_ival = v;
  225.         }
  226.     } else {
  227.         long long carry = val;
  228.         for (int i = 0; i < result.m_ival; i++) {
  229.             carry += result.m_words[i];
  230.             result.m_words[i] = (uint) carry;
  231.             carry >>= 32;
  232.         }
  233.         if (carry > 0) {
  234.             result.doCarry(carry);
  235.         }
  236.     }

  237.     return result;
  238. }

  239. BigInteger BigInteger::add(const BigInteger& bint, int val) const
  240. {
  241.     BigInteger result = bint;

  242.     if (result.compareSign(val)) {
  243.         val = val & 0x7fffffff; // abs();
  244.         if (result.m_words == NULL) {
  245.             long long sum = (long long) val + (long long) result.m_ival;
  246.             uint v = (uint) sum;
  247.             if ((long long) v != sum) {
  248.                 result.m_words = new uint[32];
  249.                 result.m_sizeOfWords = 32;
  250.                 result.m_ival = 2;
  251.                 result.m_words[0] = v;
  252.                 result.m_words[1] = sum >> 32;
  253.             } else {
  254.                 result.m_ival = v;
  255.             }
  256.         } else {
  257.             long long carry = val;
  258.             for (int i = 0; i < result.m_ival; i++) {
  259.                 carry += result.m_words[i];
  260.                 result.m_words[i] = (uint) carry;
  261.                 carry >>= 32;
  262.             }
  263.             if (carry > 0) {
  264.                 result.doCarry(carry);
  265.             }
  266.         }
  267.     }
  268.     return result;
  269. }

  270. /** Add x[0:len-1] and y[0:len-1] and write the len least
  271.  * significant words of the result to dest[0:len-1].
  272.  * All words are treated as unsigned.
  273.  * @return the carry, either 0 or 1
  274.  * This function is basically the same as gmp's mpn_add_n.
  275.  */
  276. uint BigInteger::MPN_add_n(uint dest[], const uint x[], const uint y[], int len) const
  277. {
  278.     ullong carry = 0;
  279.     for (int i = 0; i < len; i++)
  280.     {
  281.         carry += ((ullong) x[i] & 0xffffffffL)
  282.             + ((ullong) y[i] & 0xffffffffL);
  283.         dest[i] = (uint) carry;
  284.         carry >>= 32;
  285.     }
  286.     return (uint) carry;
  287. }

  288. bool BigInteger::compareSign(int val) const
  289. {
  290.     if ((m_sign == 0 && val == 0)
  291.         || (m_sign > 0 && val > 0)
  292.         || (m_sign < 0 && val < 0)) {
  293.         return true;
  294.     }

  295.     return false;
  296. }

  297. bool BigInteger::compareSign(BigInteger& val) const
  298. {
  299.     if (m_sign != val.m_sign) {
  300.         return false;
  301.     }

  302.     return true;
  303. }


  304. void BigInteger::doCarry(unsigned int val)
  305. {
  306.     expandWords();
  307.     m_words[m_ival++] = val;
  308. }

  309. void BigInteger::expandWords()
  310. {
  311.     uint* newWords = new uint[m_sizeOfWords+32];
  312.     memset(newWords, 0, m_sizeOfWords+32 * sizeof(uint));
  313.     memcpy(newWords, m_words, m_sizeOfWords * sizeof(uint));
  314.     delete[] m_words;
  315.     m_words = newWords;
  316.     m_sizeOfWords += 32;
  317. }

  318. void BigInteger::expandWords(int newSize)
  319. {
  320.     if (m_words != NULL && m_sizeOfWords >= newSize) {
  321.         return;
  322.     }

  323.     uint* newWords = new uint[newSize];
  324.     memset(newWords, 0, newSize * sizeof(uint));

  325.     if (m_words == NULL) {
  326.         memcpy(newWords, m_words, m_sizeOfWords * sizeof(uint));
  327.     } else {
  328.         delete[] m_words;
  329.     }
  330.     m_words = newWords;
  331.     m_sizeOfWords = newSize;
  332. }

  333. std::string BigInteger::toStdString() const
  334. {
  335.     std::string str;
  336.     format(10, str);
  337. #if 0
  338.     std::stringstream ss;
  339.     std::string str;
  340.     if (m_words == NULL) {
  341.         if (0 == m_ival) {
  342.             str = "0";
  343.             return str;
  344.         } else {
  345.             if (m_sign < 0) {
  346.                 str += "-";
  347.             }
  348.             ss << m_ival;
  349.             std::string s;
  350.             ss >> s;
  351.             str += s;
  352.         }
  353.     } else { // m_words != NULL
  354.         if (m_sign < 0) {
  355.             str += "-";
  356.         }
  357.         for (int i = m_ival-1; i >= 0; i--) {
  358.             ss << m_words[i];
  359.         }
  360.         std::string s;
  361.         ss >> s;
  362.         str += s;
  363.     }
  364. #endif

  365.     return str;
  366. }

  367. /* Divide (unsigned long) N by (unsigned int) D.
  368. * Returns (remainder << 32)+(unsigned int)(quotient).
  369. * Assumes (unsigned int)(N>>32) < (unsigned int)D.
  370. * Code transcribed from gmp-2.0's mpn_udiv_w_sdiv function.
  371. *
  372. * It's OK
  373. */
  374. ullong BigInteger::udiv_qrnnd(ullong N, uint D) const
  375. {
  376.     ullong q, r;
  377.     ullong a1 = N >> 32;
  378.     ullong a0 = N & 0xffffffffL;
  379.     if (D >= 0)
  380.     {
  381.         if (a1 < ((D - a1 - (a0 >> 31)) & 0xffffffffL))
  382.         {
  383.             /* dividend, divisor, and quotient are nonnegative */
  384.             q = N / D;
  385.             r = N % D;
  386.         }
  387.         else
  388.         {
  389.             /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
  390.             ullong c = N - ((ullong) D << 31);
  391.             /* Divide (c1*2^32 + c0) by d */
  392.             q = c / D;
  393.             r = c % D;
  394.             /* Add 2^31 to quotient */
  395.             q += 1 << 31;
  396.         }
  397.     }
  398.     else
  399.     {
  400.         ullong b1 = D >> 1; /* d/2, between 2^30 and 2^31 - 1 */
  401.         //long c1 = (a1 >> 1); /* A/2 */
  402.         //int c0 = (a1 << 31) + (a0 >> 1);
  403.         ullong c = N >> 1;
  404.         if (a1 < b1 || (a1 >> 1) < b1)
  405.         {
  406.             if (a1 < b1)
  407.             {
  408.                 q = c / b1;
  409.                 r = c % b1;
  410.             }
  411.             else /* c1 < b1, so 2^31 <= (A/2)/b1 < 2^32 */
  412.             {
  413.                 c = ~(c - (b1 << 32));
  414.                 q = c / b1; /* (A/2) / (d/2) */
  415.                 r = c % b1;
  416.                 q = (~q) & 0xffffffffL; /* (A/2)/b1 */
  417.                 r = (b1 - 1) - r; /* r < b1 => new r >= 0 */
  418.             }
  419.             r = 2 * r + (a0 & 1);
  420.             if ((D & 1) != 0)
  421.             {
  422.                 if (r >= q) {
  423.                     r = r - q;
  424.                 } else if (q - r <= ((ullong) D & 0xffffffffL)) {
  425.                     r = r - q + D;
  426.                     q -= 1;
  427.                 } else {
  428.                     r = r - q + D + D;
  429.                     q -= 2;
  430.                 }
  431.             }
  432.         }
  433.         else /* Implies c1 = b1 */
  434.         { /* Hence a1 = d - 1 = 2*b1 - 1 */
  435.             if (a0 >= ((ullong)(-D) & 0xffffffffL))
  436.             {
  437.                 q = -1;
  438.                 r = a0 + D;
  439.             }
  440.             else
  441.             {
  442.                 q = -2;
  443.                 r = a0 + D + D;
  444.             }
  445.         }
  446.     }

  447.     return (r << 32) | (q & 0xFFFFFFFFl);
  448. }


  449. /** Divide divident[0:len-1] by (unsigned int)divisor.
  450. * Write result into quotient[0:len-1.
  451. * Return the one-word (unsigned) remainder.
  452. * OK for quotient==dividend.
  453. */
  454. uint BigInteger::divmod_1(uint quotient[], uint dividend[],
  455.                           int len, uint divisor) const
  456. {
  457.     int i = len - 1;
  458.     ullong r = dividend[i];
  459.     if ((r & 0xffffffffL) >= ((ullong)divisor & 0xffffffffL))
  460.         r = 0;
  461.     else
  462.     {
  463.         quotient[i--] = 0;
  464.         r <<= 32;
  465.     }

  466.     for (; i >= 0; i--)
  467.     {
  468.         uint n0 = dividend[i];
  469.         r = (r & 0xffffffff00000000) | (n0 & 0xffffffffL);
  470.         r = udiv_qrnnd (r, divisor);
  471.         quotient[i] = (uint) r;
  472.     }
  473.     return (uint)(r >> 32);
  474. }


  475. //
  476. // Only support radix 10
  477. //
  478. void BigInteger::format(int radix, std::string& buffer) const
  479. {
  480.     if (m_words == NULL) {
  481.         std::stringstream ss;
  482.         ss << m_ival;
  483.         buffer += ss.str();
  484.     } else if (m_ival <= 2) {
  485.         std::stringstream ss;
  486.         ss << longValue();
  487.         buffer += ss.str();
  488.     } else {
  489.         bool neg = isNegative();
  490.         uint *work;
  491.         if (neg || radix != 16) {
  492.             // work = new uint(m_ival);
  493.             // getAbsolute(work); // commented by xfye
  494.             work = m_words;
  495.         }
  496.         else {
  497.             work = m_words;
  498.         }
  499.         uint len = m_ival;

  500.         if (radix == 16) {
  501. #if 0
  502.             if (neg)
  503.                 buffer.append('-');
  504.             int buf_start = buffer.length();
  505.             for (int i = len; --i >= 0; )
  506.             {
  507.                 int word = work[i];
  508.                 for (int j = 8; --j >= 0; )
  509.                 {
  510.                     int hex_digit = (word >> (4 * j)) & 0xF;
  511.                     // Suppress leading zeros:
  512.                     if (hex_digit > 0 || buffer.length() > buf_start)
  513.                         buffer.append(Character.forDigit(hex_digit, 16));
  514.                 }
  515.             }
  516. #endif
  517.         } else {
  518.             for (;;) {
  519.                 int digit = divmod_1(work, work, len, radix);
  520.                 buffer.push_back(digit+'0');
  521.                 while (len > 0 && work[len-1] == 0) {
  522.                     len--;
  523.                 }
  524.                 if (len == 0) {
  525.                     break;
  526.                 }
  527.             }
  528.             if (neg) {
  529.                 buffer.push_back('-');
  530.             }

  531. #if 1
  532.             /* Reverse buffer. */
  533.             int i = 0;
  534.             int j = buffer.length() - 1;
  535.             while (i < j)
  536.             {
  537.                 char tmp = buffer[i];
  538.                 buffer[i] = buffer[j];
  539.                 buffer[j] = tmp;
  540.                 i++; j--;
  541.             }
  542. #endif
  543.         }
  544.     }
  545. }

  546. bool BigInteger::isNegative() const
  547. {
  548.     if (m_sign < 0) {
  549.         return true;
  550.     }
  551.     return false;
  552. }

  553. ullong BigInteger::longValue() const
  554. {
  555.     if (NULL == m_words) {
  556.         return (ullong) m_ival;
  557.     }
  558.     if (m_ival == 1) {
  559.         return (ullong) m_words[0];
  560.     }
  561.     return ((ullong) m_words[1] << 32) + ((ullong) m_words[0] & 0xffffffff);
  562. }

  563. void BigInteger::debug()
  564. {
  565.     uint work[] = { 0x63, 0x01, 0x05 };
  566.     uint r = divmod_1(work, work, 3, 10);
  567.     std::cout << "[debug] r=" << r << std::endl;

  568.     //ullong a = 0x100000000;
  569.     //ullong b = udiv_qrnnd(a, 10);
  570.     //std::cout << "debug:: " << b << std::endl;
  571. }

  572. BigInteger BigInteger::times(const BigInteger& bint, uint val) const
  573. {
  574.     BigInteger result;

  575.     if (val == 0) {
  576.         result.assign(0);
  577.         return result;
  578.     }
  579.     if (val == 1) {
  580.         result = bint;
  581.         return result;
  582.     }

  583.     if (bint.m_words == NULL) {
  584.         result.assign((ullong) m_ival * (ullong) val);
  585.         return result;
  586.     }

  587.     result = bint;
  588.     result.expandWords();
  589.     result.m_words[result.m_ival] = mul_1(result.m_words, result.m_words, result.m_ival, val);
  590.     result.m_ival++;
  591.     result.canonicalize();
  592.     return result;
  593. }

  594. BigInteger BigInteger::times(const BigInteger& bint, int y) const
  595. {
  596.     BigInteger result;

  597. #if 1
  598.     if (y == 0) {
  599.         result.assign(0);
  600.         return result;
  601.     }
  602.     if (y == 1) {
  603.         result = bint;
  604.         return result;
  605.     }

  606.     if (bint.m_words == NULL) {
  607.         result.assign((ullong) m_ival * (ullong) y);
  608.         if (bint.compareSign(y)) {
  609.             result.m_sign = 1;
  610.         } else {
  611.             result.m_sign = -1;
  612.         }
  613.         return result;
  614.     }

  615.     result = bint;
  616.     result.expandWords();
  617.     result.m_words[result.m_ival] = mul_1(result.m_words, result.m_words, result.m_ival, y);
  618.     result.m_ival++;
  619.     if (bint.compareSign(y)) {
  620.         result.m_sign = 1;
  621.     } else {
  622.         result.m_sign = -1;
  623.     }

  624.     result.canonicalize();
  625.     return result;

  626. #endif
  627. }

  628. /** Multiply x[0:len-1] by y, and write the len least
  629.  * significant words of the product to dest[0:len-1].
  630.  * Return the most significant word of the product.
  631.  * All values are treated as if they were unsigned
  632.  * (i.e. masked with 0xffffffffL).
  633.  * OK if dest==x (not sure if this is guaranteed for mpn_mul_1).
  634.  * This function is basically the same as gmp's mpn_mul_1.
  635.  */
  636. uint BigInteger::mul_1(uint* dest, const uint* x, int len, uint y) const
  637. {
  638.     ullong yword = (ullong) y & 0xffffffffL;
  639.     ullong carry = 0;
  640.     for (int j = 0; j < len; j++)
  641.     {
  642.         carry += ((ullong) x[j] & 0xffffffffL) * yword;
  643.         dest[j] = (uint) carry;
  644.         carry >>= 32;
  645.     }
  646.     return (uint) carry;
  647. }

  648. /**
  649.  * Multiply x[0:xlen-1] and y[0:ylen-1], and
  650.  * write the result to dest[0:xlen+ylen-1].
  651.  * The destination has to have space for xlen+ylen words,
  652.  * even if the result might be one limb smaller.
  653.  * This function requires that xlen >= ylen.
  654.  * The destination must be distinct from either input operands.
  655.  * All operands are unsigned.
  656.  * This function is basically the same gmp's mpn_mul. */

  657. void BigInteger::mul (uint dest[],
  658.                       const uint x[], int xlen,
  659.                       const uint y[], int ylen) const
  660. {
  661.     dest[xlen] = mul_1 (dest, x, xlen, y[0]);

  662.     for (int i = 1; i < ylen; i++)
  663.     {
  664.         ullong yword = (ullong) y[i] & 0xffffffffL;
  665.         ullong carry = 0;
  666.         for (int j = 0; j < xlen; j++)
  667.         {
  668.             carry += ((ullong) x[j] & 0xffffffffL) * yword
  669.                 + ((ullong) dest[i+j] & 0xffffffffL);
  670.             dest[i+j] = (uint) carry;
  671.             carry >>= 32;
  672.         }
  673.         dest[i+xlen] = (uint) carry;
  674.     }
  675. }

  676. BigInteger& BigInteger::operator *=(int val)
  677. {
  678.     *this = times(*this, val);
  679.     return *this;
  680. }

  681. BigInteger& BigInteger::operator *=(uint val)
  682. {
  683.     *this = times(*this, val);
  684.     return *this;
  685. }

  686. BigInteger& BigInteger::operator *=(BigInteger& val)
  687. {
  688.     *this = times(*this, val);
  689.     return *this;
  690. }

  691. BigInteger& BigInteger::operator =(unsigned int val)
  692. {
  693.     assign(val);
  694.     return *this;
  695. }

  696. BigInteger& BigInteger::operator =(int val)
  697. {
  698.     assign(val);
  699.     return *this;
  700. }

  701. BigInteger& BigInteger::operator =(ullong val)
  702. {
  703.     assign(val);
  704.     return *this;
  705. }

  706. BigInteger& BigInteger::operator =(const BigInteger& val)
  707. {
  708.     assign(val);
  709.     return *this;
  710. }

  711. bool BigInteger::operator !=(int val)
  712. {
  713.     if (!compareSign(val)) {
  714.         return true;
  715.     }
  716.     if (m_words != NULL) {
  717.         return true;
  718.     }
  719.     if (m_ival != val) {
  720.         return true;
  721.     }

  722.     return true;
  723. }

  724. bool BigInteger::operator ==(int val)
  725. {
  726.     if (!compareSign(val)) {
  727.         return false;
  728.     }
  729.     if (m_words != NULL) {
  730.         return false;
  731.     }
  732.     if (m_ival != val) {
  733.         return false;
  734.     }

  735.     return true;
  736. }

  737. BigInteger BigInteger::times(const BigInteger& x, const BigInteger& y) const
  738. {
  739. #if 1
  740.     if (y.m_words == NULL) {
  741.         return times(x, y.m_ival);
  742.     }

  743.     if (x.m_words == NULL) {
  744.         return times(y, x.m_ival);
  745.     }

  746.     uint *xwords = x.m_words;
  747.     uint *ywords = y.m_words;
  748.     int xlen = x.m_ival;
  749.     int ylen = y.m_ival;
  750.     if (xlen < ylen) {
  751.         int tlen = xlen; xlen = ylen; ylen = tlen;
  752.         uint* twords = xwords; xwords = ywords; ywords = twords;
  753.     }
  754.     BigInteger result;
  755.     result.expandWords(xlen + ylen);
  756.     mul(result.m_words, xwords, xlen, ywords, ylen);
  757.     result.m_ival = xlen+ylen;
  758.     return result;
  759. #endif
  760. }

  761. BigInteger& BigInteger::operator +=(int val)
  762. {
  763.     *this = add(*this, val);
  764.     return *this;
  765. }

  766. BigInteger& BigInteger::operator +=(uint val)
  767. {
  768.     *this = add(*this, val);
  769.     return *this;
  770. }

  771. BigInteger& BigInteger::operator +=(const BigInteger& val)
  772. {
  773.     BigInteger bint = add(*this, val);
  774.     *this = bint;
  775.     return *this;
  776. }

  777. void BigInteger::canonicalize()
  778. {
  779.     if (m_words != NULL
  780.         && (m_ival = wordsNeeded(m_words, m_ival)) <= 1) {
  781.         if (m_ival == 1) {
  782.             m_ival = m_words[0];
  783.         }
  784.         delete[] m_words;
  785.         m_words = NULL;
  786.     }
  787. #if 0
  788.     if (words == null && ival >= minFixNum && ival <= maxFixNum)
  789.         return smallFixNums[ival - minFixNum];
  790. #endif
  791. }

  792. /** Calculate how many words are significant in words[0:len-1].
  793.  * Returns the least value x such that x>0 && words[0:x-1]==words[0:len-1],
  794.  * when words is viewed as a 2's complement integer.
  795.  */
  796. int BigInteger::wordsNeeded(const uint words[], int len) const
  797. {
  798.     int i = len;
  799.     if (i > 0) {
  800.         int word = words[--i];
  801.         if (word == -1)
  802.         {
  803.             while (i > 0 && (word = words[i - 1]) < 0)
  804.             {
  805.                 i--;
  806.                 if (word != -1) break;
  807.             }
  808.         }
  809.         else
  810.         {
  811.             while (word == 0 && i > 0 && (word = words[i - 1]) >= 0) i--;
  812.         }
  813.     }
  814.     return i + 1;
  815. }

  816. BigInteger g_cache[1001];

  817. BigInteger& calcTreeNum(int n)
  818. {
  819.     if (g_cache[n] != 0) {
  820.         // cout << "1:" << g_cache[n] << endl;
  821.         return g_cache[n];
  822.     }

  823.     if (n == 1) {
  824.         g_cache[1] = 1;
  825.         //cout << "2:" << g_cache[n] << endl;
  826.         return g_cache[1];
  827.     }
  828.     if (n == 2) {
  829.         g_cache[2] = 2;
  830.         return g_cache[2];
  831.     }
  832.     for (int i = n-1; i >= n/2; i--) {
  833.         if (i == (n-1)/2) {
  834.             if (g_cache[i] == 0) {
  835.                 calcTreeNum(i);
  836.             }
  837.             BigInteger& bint = g_cache[i];
  838.             BigInteger v = bint;
  839.             v *= bint;
  840.             g_cache[n] += v;
  841.         } else {
  842.             if (g_cache[i] == 0) {
  843.                 calcTreeNum(i);
  844.             }
  845.             BigInteger b1 = g_cache[i];
  846.             if (n - i > 2) {
  847.                 if (g_cache[n-i-1] == 0) {
  848.                     calcTreeNum(n-i-1);
  849.                 }
  850.                 BigInteger& b2 = g_cache[n-i-1];
  851.                 BigInteger v = b1;
  852.                 v *= b2;
  853.                 v *= 2;
  854.                 g_cache[n] += v;
  855.             } else {
  856.                 b1 *= 2;
  857.                 g_cache[n] += b1;
  858.             }
  859.         }
  860.     }

  861.     //cout << "3:" << g_cache[n] << endl;
  862.     return g_cache[n];
  863. }

  864. int main()
  865. {
  866.     int n = 0;

  867.     g_cache[0] = 1;
  868.     g_cache[1] = 1;

  869.     BigInteger bint;

  870.     for (int j = 2; j < 1001; j++) {
  871.         for (int i = 1; i <= j; i++) {
  872.             bint = g_cache[j-i];
  873.             bint *= g_cache[i-1];
  874.             g_cache[j] += bint;
  875.         }
  876.     }

  877.     while (cin >> n) {
  878.         cout << g_cache[n].toStdString() << endl;
  879.     }

  880.     return 0;
  881. }

阅读(1010) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~