一般大数,常常是在JAVA里用bigInteger来写,但是在C++里也有大数的类,今天看长春赛结题报告的时候突然有看到,似乎很强大的样子。 HDU4762
Cut the Cake
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 640 Accepted Submission(s): 311
Problem Description
MMM got a big big big cake,and invited all her M friends to eat the cake together. Surprisingly one of her friends HZ took some (N) strawberries which MMM likes very much to decorate the cake (of course they also eat strawberries,not just for decoration). HZ is in charge of the decoration,and he thinks that it's not a big deal that he put the strawberries on the cake randomly one by one. After that,MMM would cut the cake into M pieces of sector with equal size and shape (the last one came to the party will have no cake to eat),and choose one piece first. MMM wants to kNow the probability that she can get all N strawberries,can you help her? As the cake is so big,all strawberries on it Could be treat as points.
Input
First line is the integer T,which means there are T cases.
For each case,two integers M,N indicate the number of her friends and the number of strawBerry.
(2 < M,N <= 20,T <= 400)
For each case,two integers M,N indicate the number of her friends and the number of strawBerry.
(2 < M,N <= 20,T <= 400)
Output
As the probability Could be very small,you should output the probability in the form of a fraction in lowest terms. For each case,output the probability in a single line. Please see the sample for more details.
Sample Input
2 3 3 3 4
Sample Output
1/3 4/27
Source
用这题Jacob的代码来记录下大数类模板
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <limits> #include <cstdlib> using namespace std; const int MAXD = 500,DIG = 9,BASE = 1000000000; const unsigned long long BOUND = numeric_limits <unsigned long long> :: max () - (unsigned long long) BASE * BASE; class bignum { private: int digits[MAXD]; int D; public: friend ostream &operator<<(ostream &out,bignum &c); inline void trim() { while(D > 1 && digits[D-1] == 0 ) D--; } inline void dealint(long long x) { memset(digits,sizeof(digits)); D=0; do { digits[D++]=x%BASE; x/=BASE; } while(x>0); } inline void dealstr(char *s) { memset(digits,sizeof(digits)); int len = strlen(s),first = (len + DIG -1)%DIG + 1; D = (len+DIG-1)/DIG; for(int i = 0; i < first; i++) digits[D-1] = digits[D-1]*10 + s[i] - '0'; for(int i = first,d = D-2; i < len; i+=DIG,d--) for(int j = i; j < i+DIG; j++) digits[d] = digits[d]*10 + s[j]-'0'; trim(); } inline char *print() { trim(); char *cdigits = new char[DIG * D + 1]; int pos = 0,d = digits[D-1]; do { cdigits[pos++] = d % 10 + '0'; d/=10; } while(d > 0); reverse(cdigits,cdigits+pos); for(int i = D - 2; i >= 0; i--,pos += DIG) for(int j = DIG-1,t = digits[i]; j >= 0; j--) { cdigits[pos+j] = t%10 + '0'; t /= 10; } cdigits[pos] = '\0'; return cdigits; } bignum() { dealint(0); } bignum(long long x) { dealint(x); } bignum(int x) { dealint(x); } bignum(char *s) { dealstr(s); } inline bool operator < (const bignum &o) const { if(D != o.D) return D < o.D; for(int i = D-1; i>=0; i--) if(digits[i] != o.digits[i]) return digits[i] < o.digits[i]; return false; //equal } bool operator > (const bignum & o)const { return o < *this; } bool operator <= (const bignum & o)const { return !(o < *this); } bool operator >= (const bignum & o)const { return !(*this < o); } bool operator != (const bignum & o)const { return o < *this || *this < o; } bool operator == (const bignum & o)const { return !(o < *this) && !(*this < o); } bignum &operator++() { *this = *this + 1; return *this; } bignum operator ++(int) { bignum old = *this; ++(*this); return old; } inline bignum operator << (int p) const { bignum temp; temp.D = D + p; for (int i = 0; i < D; i++) temp.digits [i + p] = digits [i]; for (int i = 0; i < p; i++) temp.digits [i] = 0; return temp; } inline bignum operator >> (int p) const { bignum temp; temp.D = D - p; for (int i = 0; i < D - p; i++) temp.digits [i] = digits [i + p]; for (int i = D - p; i < D; i++) temp.digits [i] = 0; return temp; } bignum &operator += (const bignum &b) { *this = *this + b; return *this; } bignum &operator -= (const bignum &b) { *this = *this - b; return *this; } bignum &operator *= (const bignum &b) { *this = *this * b; return *this; } bignum &operator /= (const bignum &b) { *this = *this / b; return *this; } bignum &operator %= (const bignum &b) { *this = *this % b; return *this; } inline bignum operator + (const bignum &o) const { bignum sum = o; int carry = 0; for (sum.D = 0; sum.D < D || carry > 0; sum.D++) { sum.digits [sum.D] += (sum.D < D ? digits [sum.D] : 0) + carry; if (sum.digits [sum.D] >= BASE) { sum.digits [sum.D] -= BASE; carry = 1; } else carry = 0; } sum.D = max (sum.D,o.D); sum.trim (); return sum; } inline bignum operator - (const bignum &o) const { bignum diff = *this; for (int i = 0,carry = 0; i < o.D || carry > 0; i++) { diff.digits [i] -= (i < o.D ? o.digits [i] : 0) + carry; if (diff.digits [i] < 0) { diff.digits [i] += BASE; carry = 1; } else carry = 0; } diff.trim (); return diff; } inline bignum operator * (const bignum &o) const { bignum prod = 0; unsigned long long sum = 0,carry = 0; for (prod.D = 0; prod.D < D + o.D - 1 || carry > 0; prod.D++) { sum = carry % BASE; carry /= BASE; for (int j = max (prod.D - o.D + 1,0); j <= min (D - 1,prod.D); j++) { sum += (unsigned long long) digits [j] * o.digits [prod.D - j]; if (sum >= BOUND) { carry += sum / BASE; sum %= BASE; } } carry += sum / BASE; prod.digits [prod.D] = sum % BASE; } prod.trim (); return prod; } inline bignum range (int a,int b) const { bignum temp = 0; temp.D = b - a; for (int i = 0; i < temp.D; i++) temp.digits [i] = digits [i + a]; return temp; } inline double double_div (const bignum &o) const { double val = 0,oval = 0; int num = 0,onum = 0; for (int i = D - 1; i >= max (D - 3,0); i--,num++) val = val * BASE + digits [i]; for (int i = o.D - 1; i >= max (o.D - 3,onum++) oval = oval * BASE + o.digits [i]; return val / oval * (D - num > o.D - onum ? BASE : 1); } inline pair <bignum,bignum> divmod (const bignum &o) const { bignum quot = 0,rem = *this,temp; for (int i = D - o.D; i >= 0; i--) { temp = rem.range (i,rem.D); int div = (int) temp.double_div (o); bignum mult = o * div; while (div > 0 && temp < mult) { mult = mult - o; div--; } while (div + 1 < BASE && !(temp < mult + o)) { mult = mult + o; div++; } rem = rem - (o * div << i); if (div > 0) { quot.digits [i] = div; quot.D = max (quot.D,i + 1); } } quot.trim (); rem.trim (); return make_pair (quot,rem); } inline bignum operator / (const bignum &o) const { return divmod (o).first; } inline bignum operator % (const bignum &o) const { return divmod (o).second; } inline bignum power (int exp) const { bignum p = 1,temp = *this; while (exp > 0) { if (exp & 1) p = p * temp; if (exp > 1) temp = temp * temp; exp >>= 1; } return p; } inline bignum factorial() const { bignum ans = 1,num = *this; if (num == 0 || num == 1) return ans; while (!(num < 0 || num == 0)) { ans = ans * num; num = num - 1; } return ans; } }; ostream &operator<<(ostream &out,bignum &c) { out<<c.print(); return out; } istream &operator >> (istream &in,bignum &c) { char s[500]; in>>s; c = s; return in; } bignum gcd(bignum a,bignum b) { return b==0?a:gcd(b,a%b); } bignum N,M,x; int main() { int cases,i,a,b; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); cin>>cases; while (cases--) { cin>>b>>a; M=1; for (i=1;i<=a-1;i++) M=M*b; N=a; x=gcd(N,M); N=N/x; M=M/x; cout<<N<<"/"<<M<<endl; } return 0; }
再用一个同是长春赛区的Kuangbin的解题报告 HDU4759
Poker Shuffle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 370 Accepted Submission(s): 114
Problem Description
Jason is not only an Acmer,but also a poker nerd. He is able to do a perfect shuffle. In a perfect shuffle,the deck containing K cards,where K is an even number,is split into equal halves of K/2 cards which are then pushed together in a certain way so as to make them perfectly interweave. Suppose the order of the cards is (1,2,3,4,…,K-3,K-2,K-1,K). After a perfect shuffle,the order of the cards will be (1,K) or (2,K,1,K-1).
Suppose K=2^N and the order of the cards is (1,K) in the beginning,is it possible that the A-th card is X and the B-th card is Y after several perfect shuffles?
Suppose K=2^N and the order of the cards is (1,K) in the beginning,is it possible that the A-th card is X and the B-th card is Y after several perfect shuffles?
Input
Input to this problem will begin with a line containing a single integer T indicating the number of datasets.
Each case contains five integer,N,A,X,B,Y. 1 <= N <= 1000,1 <= A,Y <= 2^N.
Each case contains five integer,N,A,X,B,Y. 1 <= N <= 1000,1 <= A,Y <= 2^N.
Output
For each input case,output “Yes” if it is possible that the A-th card is X and the B-th card is Y after several perfect shuffles,otherwise “No”.
3
1 1 1 2 2
2 1 2 4 3
2 1 1 4 2
Case 1: Yes
Case 2: Yes
Case 3: No