Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
大牛!!!In Reply To:n!计算的一些优化 Posted by:gemenhao at 2006-06-29 14:20:44 > AI上的2731题计算n!时间主要花费乘法上 ,我的代码有如下优化措施 > 1: > 采用10^n进制(n <= 9),要注意乘法溢出,可以采用一些手段防止出现这种情况 > 采用10^7以下进制计算是可以保证不溢出,但是这样会慢一些。 > > void multiply(int64* multiplicand, int t_length){ > int new_length = m_length + t_length; > memset(s_buffer, 0, (new_length + 2) << 3); > for (int t = t_length - 1; t >= 0; --t) > for (int m = m_length - 1; m >= 0; --m){ > s_buffer[m + t] += m_digit[m] * multiplicand[t]; > #ifdef D9 //D9 表示定了BASE 为 10^9 > if (s_buffer[m + t] > MaxLong){ > s_buffer[m + t + 1] += s_buffer[m + t] / BASE; > s_buffer[m + t] %= BASE; > } > #endif > > } > } > 然后进位 > > 2: > 计算中进位要占用时间,因此采用分治计算,然后各个区间的乘积再相乘 > LEN 是(1,n)分成最大的区间个数。 > > factorial *hyb[500]; > for (int j = 0; j < LEN; j++){ > int beg = j * n / LEN; > int end = (j + 1) * n / LEN; > hyb[j] = new factorial(beg + 1, end); > } > // 累计相乘各个区间积 > while (w < LEN){ > for(int i = 0; i < LEN; i += w * 2) > (*hyb[i]) *= (*hyb[i + w]); > w *= 2; > } > 3: > 每一个区间计算尽量加快乘法,较小的数可以累计相乘到一个规定的数, > const double MaxLong = pow(2.0, 63);//累计最大值 > while(m_end >= m_beg ){ > int64 multiplicand = m_end--; > while ( (double)multiplicand * m_end < MaxLong && m_end >= m_beg ) > multiplicand *= m_end--; > multiplicand = devide_5(multiplicand);//除去5因子 > int leng = convert_multiplicand(multiplicand);//转换成BASE进制数组 > *this *= leng ; > } > 4:计算中末尾连续0不参与计算,只作标记。 > > > Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator