I use this formula to calculate: f(n) = (n,4) + (n,2) + 1. Detailed explanation is available here.
I really need to implement a big integer class. The following code is rather ugly.
Code:
- /*************************************************************************
- * Copyright (C) 2008 by liukaipeng *
- * liukaipeng at gmail dot com *
- *************************************************************************/
- /* @JUDGE_ID 00000 10213 C++ "How Many Pieces of Land?" */
- #include <algorithm>
- #include <cstdio>
- #include <cstring>
- #include <deque>
- #include <fstream>
- #include <iostream>
- #include <list>
- #include <map>
- #include <queue>
- #include <set>
- #include <stack>
- #include <string>
- #include <vector>
- using namespace std;
- typedef unsigned long long ulonglong;
- string add(string const& x, string const& y)
- {
- int sumlen = max(x.size(), y.size()) + 1;
- string sum(sumlen, '0'), xtmp(sumlen, '0'), ytmp(sumlen, '0');
- int xstart = sumlen - x.size(), ystart = sumlen - y.size();
- copy(x.begin(), x.end(), xtmp.begin() + xstart);
- copy(y.begin(), y.end(), ytmp.begin() + ystart);
- for (int i = sumlen-1, s, carry = 0; i >= 0; --i, carry = s / 10)
- sum[i] = (s = xtmp[i] + ytmp[i] - '0' - '0' + carry) % 10 + '0';
- for (; sum[0] == '0'; sum.erase(0, 1)) {}
- return sum;
- }
- string muladd(ulonglong x, ulonglong y, ulonglong z)
- {
- int const shift = 31;
- ulonglong x1 = x >> shift, x2 = x & ((1LL << shift) - 1);
- ulonglong y1 = y >> shift, y2 = y & ((1LL << shift) - 1);
- ulonglong z1 = z >> shift, z2 = z & ((1LL << shift) - 1);
- ulonglong high = x1*y1, mid = x1*y2 + x2*y1 + z1, low = x2*y2 + z2;
- string tmp;
- for (; high != 0; high /= 10)
- tmp.append(1, high % 10 + '0');
- string highs(tmp.rbegin(), tmp.rend());
- for (tmp.clear(); mid != 0; mid /= 10)
- tmp.append(1, mid % 10 + '0');
- string mids(tmp.rbegin(), tmp.rend());
- for (tmp.clear(); low != 0; low /= 10)
- tmp.append(1, low % 10 + '0');
- string lows(tmp.rbegin(), tmp.rend());
- for (int i = 0; i < shift*2; ++i)
- highs = add(highs, highs);
- for (int i = 0; i < shift; ++i)
- mids = add(mids, mids);
- string product = add(highs, mids);
- product = add(product, lows);
- return product;
- }
- int main(int argc, char *argv[])
- {
- #ifndef ONLINE_JUDGE
- freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
- freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
- #endif
- /* f(n) = (n,4) + (n,2) + 1 */
- int ncases;
- cin >> ncases;
- while (ncases-- > 0) {
- ulonglong n;
- cin >> n;
- if (n < 4) {
- ulonglong fn = 1;
- for (int i = 1; i < n; ++i)
- fn *= 2;
- cout << fn << '/n';
- } else if (n < 1 << 16) {
- ulonglong fn = n*(n-1)/2*(n-2)/3*(n-3)/4;
- fn += n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n;
- fn += 1;
- cout << fn << '/n';
- } else {
- ulonglong x = n*(n-1)/2, y = (n-2)*(n-3)/2;
- if (x % 2 == 0) x /= 2;
- else y /= 2;
- if (x % 3 == 0) x /= 3;
- else y /= 3;
- ulonglong z = (n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n);
- z += 1;
- string fn = muladd(x, y, z);
- cout << fn << '/n';
- }
- }
- return 0;
- }