Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

大牛!!!

Posted by 19861020 at 2006-06-29 14:24:53 on Problem 1061
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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator