HDU 5139 Formula

Formula

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 384    Accepted Submission(s): 160


Problem Description
f(n)=(i=1nini+1)%1000000007
You are expected to write a program to calculate f(n) when a certain n is given.
 

Input
Multi test cases (about 100000), every case contains an integer n in a single line. 
Please process to the end of file.

[Technical Specification]
1n10000000
 

Output
For each n,output f(n) in a single line.
 

Sample Input
   
   
   
   
2 100
 

Sample Output
   
   
   
   
2 148277692
 

Source
BestCoder Round #21

 
分析:
先给出题解:
找规律
f(1)=1
f(2)=1*1*2=(1)*(1*2)=1!*2!
f(3)=1*1*1*2*2*3=(1)*(1*2)*(1*2*3)=1!*2!*3!

式子可以简化为 
    
     f(n)=i=1n(n!)%MOD
    ,直接打表不行,会超内存,可以对数据进行离线处理。排好序之后从小到大暴力。ClogC+10000000 ,C为case数目。
当时做的时候直接求,TLE , 又进一步优化用分治法求 n^m, 还是TLE。坑,最后想到应该有技巧,对于 n = 100
f( n ) = 1^99 * 2^98 * 3^97 * 4^96 *……* 99^2 * 100 = ( 1^98 * 2^97 * 3^96 * 4^95 *……* 99) * 100! = …
最终结果为: f( n ) = 1! * 2! * 3! *……*100!
带着激动的心情提交代码,又是 TLE!脑力枯竭,还有30分钟,我选择了放弃。
比赛结束后,题解上说离线处理,以前听过离线处理,应该是那样^-^……
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#define for1( i , a , b ) for( int i = a ; i <= b ; i++ )
using namespace std ;

const int maxn = 10000010 , mod = 1000000007 ;
int a[ maxn ] , s[ maxn ] , f[ maxn ] ;

int main()
{

    int n = -1 ;
    while( ~scanf( "%d" , &a[ ++n ] ) ) s[ n ] = a[ n ] ;       // s 保持数据原来顺序
    sort( a , a + n ) ;         //由小到大排序
    long long Sum = 1 , sum = 1 , k = 1 ;
    for1( i , 0 , n - 1 ) {     //暴力求解
    	for1( j , k , a[ i ] ) {
            sum = sum * j % mod ;
	    Sum = Sum * sum % mod ;
	}
        k = a[ i ] + 1 ;
        f[ a[ i ] ] = Sum ;     //保存结果
    }
    for1( i , 0 , n - 1 ) printf( "%d\n" , f[ s[ i ] ] ) ;      //按输入顺序输出结果
    return 0;
}


你可能感兴趣的:(HDU 5139 Formula)